Exploring Risk Polarization
Introduction
Risk perception may vary among different people, across different
contexts and over time. Understanding how people perceive specific risks
enables us to pinpoint crucial factors that can inform policy
implementation, mobilize communities, and unite them under a common
goal. Thus, it is essential to investigate which events are perceived as
risky and whether there is polarization (e.g. no clear consensus).
Polarization can be measured in many different ways. A recent preprint by Fischer &
Frey have shown at least 8 different measures of polarization
itself. Depending on which measure is taken to describe polarization,
researchers, stakeholders and policy makers may arrive at different
conclusions, which hinders the decision-making process. It is therefore
of utmost importance to find a common ground.
This work tries to built the groundwork for an upcoming study, which
aims to collect risk scores of several risks. Examples of such risks are
vaccination, war, or firefighter.
Though it is still uncertain how many ratings a risk needs, so we can be
sure that it is representative for the population in question.
Therefore, a simulation approach was chosen to decide how many
participants are needed per risk.
To summarise, this work has two objectives:
- Help identify which measure(s) to take which should indicate
polarization.
- A sort of power
analysis to estimate how many ratings a risk needs.
Polarization Measures
The following 8 different measures of polarization were formulated in
the previous mentioned preprint:
- Spread (or more commonly known as Range)
- Dispersion
- Coverage
- Size Parity
- Group Divergence
- Polarization Index
- Group Distinctness (or Overlap Coefficient)
- Bimodality
Coefficient
For a more in-depth review of those measures, please refer to the preprint.
Additionally, there is one other measure of polarization which is
often used in sociology, building upon van
der Eijk’s measure of agreement A:
In order to safe time, two polarization measures were omitted in this
simulation:
- Spread is strongly influenced by one outlier (here: risk rating),
and will therefore be omitted. Most range values would be on the higher
end, and therefore, no variation would be expected.
- Group Distinctness can not be calculated in our simulation, as it
needs some categorical grouping variable. This means that the simulation
would need to create at least two underlying distributions.
All included measures can range between 0 and 1, and higher values
indicate higher polarization.
Method
The method chosen for the simulation procedure is called the
Monte Carlo simulation. At its core, the simulation
consists of random sampling and statistical analysis, provided the
underlying system can be roughly estimated or approximated with the
simulation itself. As the procedure leverages the law of large numbers,
the process takes a large number of random samples of said system to
solve a complex problem.
Probability Distributions
We use several probability distributions as a proxy for the “true”
distribution of different kinds of risks in a certain population. Using
different distributions can give us a better insight, assuming
the distribution is also representative in the population we
want to sample in.
While most things in nature is normally distributed, using the beta
distribution to illustrate a polarized distribution is also warranted.
Therefore, this simulation uses both of these distribution types as a
proxy for our risks.

To simulate different types of risk and their possible distributions,
we chose two beta distributions (a skewed beta
distribution, and a symmetrical beta
distribution), a normal distribution, as
well as a mixed
distribution which is built with two underlying normal
distributions itself.
While the two beta distributions should simulate risks that are
polarized in different manners, the normal distribution is a proxy for a
risk where there is a consensus in the population.
The mixed distribution tries to capture the distribution where a
minority (in this case with a base rate of 2%), have a
polarizing opinion compared to a majority in a population.
The Simulation Procedure
For the simulation itself, we use 21 different sample
sizes:
## [1] 80 90 100 110 120 130 140 150 160 170 180 190 200 300 400
## [16] 500 600 700 800 900 1000
Using these different sample sizes, we simulate for each of our
4 risk distributions, and replicate this procedure
50 times, which leaves us with 4200
simulations.
The grouped difference of these samples should then be compared against
the polarization measure of the whole risk distribution itself, which
functions as our “true score”.

The plot above shows a snipped of our current matrix. The matrix has
a staircase-like shape, as not every simulation has 1000 ratings. For
example, the first few rows contains only 80 ratings,
whereas at the bottom end, we have 1000 ratings. Overall,
the matrix contains 1.404\times 10^{6} risk ratings.
We use this matrix to calculate our polarization measures. Storing
these risk ratings in one big matrix (even though it has more “missing”
values) helps to avoid errors down the line, and speeds up the
calculation as well.

Results
Overall
Plot

Polarization measures in our population
distribution
True Score Table
|
Polarization
|
Dispersion
|
Coverage
|
Size Parity
|
Group Divergence
|
Polarization Index
|
Bimodality Coefficient
|
Risk Distribution
|
|
0.228
|
0.133
|
0.783
|
0.714
|
0.500
|
0.143
|
0.641
|
Skewed Beta
|
|
0.804
|
0.482
|
0.666
|
0.007
|
0.883
|
0.877
|
0.888
|
Symmetric Beta
|
|
0.235
|
0.101
|
0.814
|
0.002
|
0.237
|
0.237
|
0.342
|
Normal
|
|
0.109
|
0.041
|
0.481
|
0.960
|
0.912
|
0.036
|
0.834
|
Mixed
|
Bimodality Coefficient
Plot

Polarization
Plot

Coverage
Plot

Dispersion
Plot

Group Divergence
Plot

Polarization Index
Plots

Size Parity
Plots

Discussion
It seems like that there is a certain pattern in the plots:
As expected, the higher the sample size increases, the more the
differences between the sample and the population converges to 0,
meaning that we get a more accurate estimate.
Likewise, the error bars decline with increasing sample
size.
The different polarization measures have different strengths and
weaknesses:
- Almost all measures were able to accurately estimate the true score
on the normal
distribution, except for size parity.
Considering that this measure uses group sizes of low vs high values
split by the midpoint of a scale, setting the mean of the normal
distribution to the midpoint was a detriment to this measure.
- Size parity struggles with the skewed beta distribution
as well. It seems like partitioning the ratings into halves has its
disadvantages when sampling from something that is skewed like
that.
- Looking at the mixed
distribution, the bimodality coefficient, coverage
and group divergence had rather big error bars.
- Looking at the symmetric beta
distribution, the polarization, dispersion,
polarization index and size parity were off for smaller and even
medium sample sizes.
Overall, the mixed and symmetric beta distributions were the most
difficult for our candidate measures to approximate to the “true score”.
Sadly, these are the distributions which most would call polarized, and
which the study wants to uncover. Therefore, a greater number of ratings
is advised to reliable estimate the extend of polarization in the
population.
Being able to estimate the population with our measures is good and
all, but one important aspect of choosing a measure also includes how
much variability it has in different risks. For example, if a measure
indicates a polarization value of .5 for different risks (hence low
variability), is our chosen measure good because we can detect the true
score in the population with even small samples (as the comparison of
sample and true score was derived from the same method)? Or is it
outright bad because it is agnostic towards most risks and thus does not
detect the different nuances of a risk distribution? The best example
here would be to look at the measure coverage in our true score
distributions. It scored the best out of all the measures when only
looking at the difference to the “true score”, but on a closer look,
does not differentiate between the symmetric beta and the
normal
distributions, which most would think are totally
different. Thus, coverage may not be a good measure for polarization (or
at least not the way I see it).
Taking several measures as a operationalization of polarization is
probably a better approach than banking our study with just one. As
such, the author nominates the bimodality coefficient, polarization
and group divergence as the go to measures for the upcoming study.
These measures were taken because of the following reasons:
- These measures complement each other and compensate for each other’s
weaknesses:
- The bimodality coefficient uses skewness and kurtosis,
hence uses some sort of asymmetry and “heaviness”
detection in a distribution. However, biases in the distribution can
lead to biases in the aforementioned metrics as well, which screws the
validity of this measure. Thus it is not perfectly sensitive and
specific to assess bimodality.
- The measure of polarization acts as a sort of
agreement measure (summed weights of ordered bins). Its
strengths is its biggest flaw, as it ignores minority groups even though
they may also contribute to polarization (like our mixed
distribution).
- Group divergence is a measure which takes into account how
big the (mean) distance between two sides of a midpoint
is. The problem of this metric is that it is agnostic to the exact
distribution and group sizes.
- Are able to differentiate between different types of
distributions.
- While also being somewhat usable as a standalone measure.
Additionally, the bimodality coefficient has a
mathematically derived threshold of around \(0.\overline{5}\). Distributions under this
threshold can be taken as an indication towards unimodality, whereas
values above this threshold can be seen as an indicator towards
bimodality, something akin to polarization. Though, as already
mentioned, it also has some limitations…
With these 3 measures, the author argues for at least 100 ratings per
risk…. Though it does not seem like this work was of any help at all
concerning power
analysis…
On another note, detecting polarization also depends (as mentioned
many times before) on the underlying distribution. The measures are only
tools to detect whether something is polarized, but when something is
not polarized, there can be different reasons:
- The sample size was too small to uncover polarization.
- The measure can not detect polarization.
- The risk itself is polarized, but only in a (unknown)
subgroup.
- The risk itself is not polarized.
In accordance with the third point raised above, the decision how to
sample from the population functions as a sort of window placement. One
can zoom in and out (e.g. increase sample size and therefore power), but
when the window was set in a sub optimal way, it gets even more
difficult to sample the right people with differing opinion.
Limitations
- Scale limits in samples had to be rounded so some measures can be
calculated, which may not be appropriate (e.g. 0.073657 to 0.07). Though
our ratings are discrete as well, so this may even be more ecologicaly
valid.
- While the values of the samples were rounded, the values in the
population were not. This should not make a difference from a
mathematical perspective for the measures (more
granular/ finer detail). It may, however, hinder the comparison to our
calculated measures in the simulated samples.
- Only 4 risk distributions were simulated.
- Spread and Group Distinctness were left out in this
simulation.
- The simulation used a scale of 0 to 1 with increments of 0.01, which
also translates to 101 different scales. Whether the results still holds
for less granular scales is up for debate.
- As mentioned in the method section, the Monte Carlo approach lives
and falls with the underlying distribution, which we assume is also
present in the population. But as all things in life, the distributions
may look completely different. Irregularities and discontinuities may
even be the norm than the exception.
- Interpreting such a work is a first for me, please be wary of my
possibly biased view in this. This is also reflected in the low count in
the references, where I argue mostly with the data and intuition, which
is subjective. Please formulate your own opinion on this matter!
Conclusions
- No “one size fits all” measure, but three candidate measures of
bimodality coefficient, polarization and group divergence were
nominated.
- No clear cut answer for how many participants should be
sampled.
- While sample size plays a key role in detecting polarization,
sampling from a population where we assume polarization to be more
present is an even more important factor, as it technically sets the
“base rate” of differing opinions.
Credits
Acknowledgements and others
This work was done within 2 weeks in context of the master project in
my MSc. in psychology at the university of Basel within the CDS
department.
I thank Prof. Dr. Rui Mata for the supervision and continued guidance
in the master project.
In addition, I would like to extend my appreciation to the members in
the risk polarization group, namely:
- Goetz, Fabienne
- Leutwyler, Vanessa
- Lichtner, Lukas
- Rosa, Flavia
- Willi, Noah
The code used for this work can be downloaded in the upper right
corner in the beginning of this HTML file.
In case you have other questions or remarks, feel free to contact me
under: andy.cao@unibas.ch
Please refrain from criticizing this work for not conforming to APA
style guidelines, reporting in a non-scientific manner, and formatting
choices.
Lastly, I would like to thank those who read this whole work from top
to bottom. Simultaneously though, I would like to apologize for my
wall of text odd choice of words here and there.
R Packages used
agrmt (Ruedin D (2023). agrmt: Calculate Concentration and
Dispersion in Ordered Rating Scales. R package version 1.42.12, https://CRAN.R-project.org/package=agrmt.)
doParallel (Corporation M, Weston S (2022). doParallel:
Foreach Parallel Adaptor for the ‘parallel’ Package. R package
version 1.0.17, https://CRAN.R-project.org/package=doParallel.)
foreach (Microsoft, Weston S (2022). foreach: Provides
Foreach Looping Construct. R package version 1.5.2, https://CRAN.R-project.org/package=foreach.)
knitr (Xie Y (2023). knitr: A General-Purpose Package for
Dynamic Report Generation in R. R package version 1.45, https://yihui.org/knitr/.)
psych (William Revelle (2023). psych: Procedures for
Psychological, Psychometric, and Personality Research. Northwestern
University, Evanston, Illinois. R package version 2.3.9, https://CRAN.R-project.org/package=psych.)
RColorBrewer (Neuwirth E (2022). RColorBrewer: ColorBrewer
Palettes. R package version 1.1-3, https://CRAN.R-project.org/package=RColorBrewer.)
rmarkdown (Allaire J, Xie Y, Dervieux C, McPherson J, Luraschi J,
Ushey K, Atkins A, Wickham H, Cheng J, Chang W, Iannone R (2023).
rmarkdown: Dynamic Documents for R. R package version 2.25, https://github.com/rstudio/rmarkdown.)
tidyverse (Wickham H, Averick M, Bryan J, Chang W, McGowan LD,
François R, Grolemund G, Hayes A, Henry L, Hester J, Kuhn M, Pedersen
TL, Miller E, Bache SM, Müller K, Ooms J, Robinson D, Seidel DP, Spinu
V, Takahashi K, Vaughan D, Wilke C, Woo K, Yutani H (2019). “Welcome to
the tidyverse.” Journal of Open Source Software,
4(43), 1686. doi:10.21105/joss.01686 https://doi.org/10.21105/joss.01686.)
visdat (Tierney N (2017). “visdat: Visualising Whole Data
Frames.” JOSS, 2(16), 355. doi:10.21105/joss.00355
https://doi.org/10.21105/joss.00355, http://dx.doi.org/10.21105/joss.00355.)
Use of AI
ChatGPT 3.5 (OpenAI. 2023, https://chat.openai.com/chat):
- Giving the exoskeleton for parallel computation using multiple cores
and foreach packages.
- Pointing the author towards the “cut” function for converting
numerical values to ordered factors used for coverage and polarization
measures.
- Overall rmarkdown syntax like coloring, css styling and writing
periodic numbers.
- Writing efficient code.
- Reformulation of some sentences in the introduction section, the
explanation of Monte Carlo simulation, as well as some parts of the
conclusion section.
References
- Fischer, O., & Frey, R. (2023). The many flavors of
polarization: A systematic comparison of different conceptualizations
and contexts. https://doi.org/10.31234/osf.io/bv496
- Pfister, R., Schwarz, K. A., Janczyk, M., Dale, R., & Freeman,
J. (2013). Good things peak in pairs: A note on the bimodality
coefficient. Frontiers in Psychology, 4. https://doi.org/10.3389/fpsyg.2013.00700
- Van Der Eijk, C. (2001). Measuring agreement in ordered rating
scales. Quality & Quantity 35, 325–341. https://doi.org/10.1023/A:1010374114305
LS0tDQp0aXRsZTogIlJpc2sgUG9sYXJpemF0aW9uIFNpbXVsYXRpb24iDQphdXRob3I6ICJBbmR5IENhbyINCmRhdGU6ICIyMDI0LTAzLTE4Ig0Kb3V0cHV0Og0KICAgaHRtbF9kb2N1bWVudDoNCiAgICAgIGNzczogc3R5bGVzLmNzcw0KICAgICAgdG9jOiB0cnVlDQogICAgICBudW1iZXJfc2VjdGlvbnM6IGZhbHNlDQogICAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICAgIGNvbGxhcHNlZDogdHJ1ZQ0KICAgICAgc21vb3RoX3Njcm9sbDogZmFsc2UNCiAgICAgIGZpZy53aWR0aDogMjYNCiAgICAgIGZpZy5oZWlnaHQ6IDI2DQogICAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCi0tLQ0KDQojIEV4cGxvcmluZyBSaXNrIFBvbGFyaXphdGlvbg0KDQoNCiMjIEludHJvZHVjdGlvbiAgDQoNClJpc2sgcGVyY2VwdGlvbiBtYXkgdmFyeSBhbW9uZyBkaWZmZXJlbnQgcGVvcGxlLCBhY3Jvc3MgZGlmZmVyZW50IGNvbnRleHRzIGFuZCBvdmVyIHRpbWUuIFVuZGVyc3RhbmRpbmcgaG93IHBlb3BsZSBwZXJjZWl2ZSBzcGVjaWZpYyByaXNrcyBlbmFibGVzIHVzIHRvIHBpbnBvaW50IGNydWNpYWwgZmFjdG9ycyB0aGF0IGNhbiBpbmZvcm0gcG9saWN5IGltcGxlbWVudGF0aW9uLCBtb2JpbGl6ZSBjb21tdW5pdGllcywgYW5kIHVuaXRlIHRoZW0gdW5kZXIgYSBjb21tb24gZ29hbC4gVGh1cywgaXQgaXMgZXNzZW50aWFsIHRvIGludmVzdGlnYXRlIHdoaWNoIGV2ZW50cyBhcmUgcGVyY2VpdmVkIGFzIHJpc2t5IGFuZCB3aGV0aGVyIHRoZXJlIGlzIHBvbGFyaXphdGlvbiAoZS5nLiBubyBjbGVhciBjb25zZW5zdXMpLiAgDQoNClBvbGFyaXphdGlvbiBjYW4gYmUgbWVhc3VyZWQgaW4gbWFueSBkaWZmZXJlbnQgd2F5cy4gQSByZWNlbnQgW3ByZXByaW50IGJ5IEZpc2NoZXIgJiBGcmV5XShodHRwczovL29zZi5pby9wcmVwcmludHMvcHN5YXJ4aXYvYnY0OTYpIGhhdmUgc2hvd24gYXQgbGVhc3QgOCBkaWZmZXJlbnQgbWVhc3VyZXMgb2YgcG9sYXJpemF0aW9uIGl0c2VsZi4gRGVwZW5kaW5nIG9uIHdoaWNoIG1lYXN1cmUgaXMgdGFrZW4gdG8gZGVzY3JpYmUgcG9sYXJpemF0aW9uLCByZXNlYXJjaGVycywgc3Rha2Vob2xkZXJzIGFuZCBwb2xpY3kgbWFrZXJzIG1heSBhcnJpdmUgYXQgZGlmZmVyZW50IGNvbmNsdXNpb25zLCB3aGljaCBoaW5kZXJzIHRoZSBkZWNpc2lvbi1tYWtpbmcgcHJvY2Vzcy4gSXQgaXMgdGhlcmVmb3JlIG9mIHV0bW9zdCBpbXBvcnRhbmNlIHRvIGZpbmQgYSBjb21tb24gZ3JvdW5kLiAgDQoNClRoaXMgd29yayB0cmllcyB0byBidWlsdCB0aGUgZ3JvdW5kd29yayBmb3IgYW4gdXBjb21pbmcgc3R1ZHksIHdoaWNoIGFpbXMgdG8gY29sbGVjdCByaXNrIHNjb3JlcyBvZiBzZXZlcmFsIHJpc2tzLiBFeGFtcGxlcyBvZiBzdWNoIHJpc2tzIGFyZSAqdmFjY2luYXRpb24qLCAqd2FyKiwgb3IgKmZpcmVmaWdodGVyKi5cDQpUaG91Z2ggaXQgaXMgc3RpbGwgdW5jZXJ0YWluIGhvdyBtYW55IHJhdGluZ3MgYSByaXNrIG5lZWRzLCBzbyB3ZSBjYW4gYmUgc3VyZSB0aGF0IGl0IGlzIHJlcHJlc2VudGF0aXZlIGZvciB0aGUgcG9wdWxhdGlvbiBpbiBxdWVzdGlvbi4gVGhlcmVmb3JlLCBhIHNpbXVsYXRpb24gYXBwcm9hY2ggd2FzIGNob3NlbiB0byBkZWNpZGUgaG93IG1hbnkgcGFydGljaXBhbnRzIGFyZSBuZWVkZWQgcGVyIHJpc2suICANCg0KVG8gc3VtbWFyaXNlLCB0aGlzIHdvcmsgaGFzIHR3byBvYmplY3RpdmVzOiAgDQogIA0KLSBIZWxwIGlkZW50aWZ5IHdoaWNoIG1lYXN1cmUocykgdG8gdGFrZSB3aGljaCBzaG91bGQgaW5kaWNhdGUgcG9sYXJpemF0aW9uLiAgDQotIEEgc29ydCBvZiBbcG93ZXIgYW5hbHlzaXNdKFJpc2stUG9sYXJpemF0aW9uLVBvd2VyLUFuYWx5c2lzLmh0bWwpIHRvIGVzdGltYXRlIGhvdyBtYW55IHJhdGluZ3MgYSByaXNrIG5lZWRzLiAgDQoNCg0KIyMgUG9sYXJpemF0aW9uIE1lYXN1cmVzDQoNClRoZSBmb2xsb3dpbmcgOCBkaWZmZXJlbnQgbWVhc3VyZXMgb2YgcG9sYXJpemF0aW9uIHdlcmUgZm9ybXVsYXRlZCBpbiB0aGUgcHJldmlvdXMgbWVudGlvbmVkIHByZXByaW50Og0KDQotICAgU3ByZWFkIChvciBtb3JlIGNvbW1vbmx5IGtub3duIGFzIFJhbmdlKVwNCi0gICBEaXNwZXJzaW9uXA0KLSAgIENvdmVyYWdlXA0KLSAgIFNpemUgUGFyaXR5XA0KLSAgIEdyb3VwIERpdmVyZ2VuY2VcDQotICAgUG9sYXJpemF0aW9uIEluZGV4XA0KLSAgIEdyb3VwIERpc3RpbmN0bmVzcyAob3IgT3ZlcmxhcCBDb2VmZmljaWVudClcDQotICAgW0JpbW9kYWxpdHkgQ29lZmZpY2llbnRdKGh0dHBzOi8vZG9jdW1lbnRhdGlvbi5zYXMuY29tL2RvYy9lbi9zdGF0dWcvMTUuMi9zdGF0dWdfY2x1c3Rlcl9kZXRhaWxzMTcuaHRtKQ0KDQpGb3IgYSBtb3JlIGluLWRlcHRoIHJldmlldyBvZiB0aG9zZSBtZWFzdXJlcywgcGxlYXNlIHJlZmVyIHRvIHRoZSBbcHJlcHJpbnRdKGh0dHBzOi8vb3NmLmlvL3ByZXByaW50cy9wc3lhcnhpdi9idjQ5NikuDQoNCkFkZGl0aW9uYWxseSwgdGhlcmUgaXMgb25lIG90aGVyIG1lYXN1cmUgb2YgcG9sYXJpemF0aW9uIHdoaWNoIGlzIG9mdGVuIHVzZWQgaW4gc29jaW9sb2d5LCBidWlsZGluZyB1cG9uIFt2YW4gZGVyIEVpamsncyBtZWFzdXJlIG9mIGFncmVlbWVudCBBXShodHRwczovL2xpbmsuc3ByaW5nZXIuY29tL2FydGljbGUvMTAuMTAyMy9BOjEwMTAzNzQxMTQzMDUjY2l0ZWFzKToNCg0KLSAgIFBvbGFyaXphdGlvbg0KDQpJbiBvcmRlciB0byBzYWZlIHRpbWUsIHR3byBwb2xhcml6YXRpb24gbWVhc3VyZXMgd2VyZSBvbWl0dGVkIGluIHRoaXMgc2ltdWxhdGlvbjoNCg0KMS4gIFNwcmVhZCBpcyBzdHJvbmdseSBpbmZsdWVuY2VkIGJ5IG9uZSBvdXRsaWVyIChoZXJlOiByaXNrIHJhdGluZyksIGFuZCB3aWxsIHRoZXJlZm9yZSBiZSBvbWl0dGVkLiBNb3N0IHJhbmdlIHZhbHVlcyB3b3VsZCBiZSBvbiB0aGUgaGlnaGVyIGVuZCwgYW5kIHRoZXJlZm9yZSwgbm8gdmFyaWF0aW9uIHdvdWxkIGJlIGV4cGVjdGVkLg0KMi4gIEdyb3VwIERpc3RpbmN0bmVzcyBjYW4gbm90IGJlIGNhbGN1bGF0ZWQgaW4gb3VyIHNpbXVsYXRpb24sIGFzIGl0IG5lZWRzIHNvbWUgY2F0ZWdvcmljYWwgZ3JvdXBpbmcgdmFyaWFibGUuIFRoaXMgbWVhbnMgdGhhdCB0aGUgc2ltdWxhdGlvbiB3b3VsZCBuZWVkIHRvIGNyZWF0ZSBhdCBsZWFzdCB0d28gdW5kZXJseWluZyBkaXN0cmlidXRpb25zLiAgDQoNCkFsbCBpbmNsdWRlZCBtZWFzdXJlcyBjYW4gcmFuZ2UgYmV0d2VlbiAwIGFuZCAxLCBhbmQgaGlnaGVyIHZhbHVlcyBpbmRpY2F0ZSBoaWdoZXIgcG9sYXJpemF0aW9uLg0KDQpgYGB7ciBTZXR1cCwgaW5jbHVkZT1UUlVFLCB3YXJuaW5nPUZBTFNFLCBlcnJvcj1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgZWNobz1GQUxTRX0NCg0KbGlicmFyeSh0aWR5dmVyc2UpICNkYXRhIHdyYW5nbGluZyBhbmQgb3RoZXIgdG9vbHMgZm9yIFINCmxpYnJhcnkoa25pdHIpICMgcmVwb3J0IGdlbmVyYXRpb24gaW4gUg0KbGlicmFyeShwc3ljaCkgI2NhbGN1bGF0ZSBza2V3IGFuZCBrdXJ0b3NpcyBmb3IgQkMNCmxpYnJhcnkoYWdybXQpICNmb3IgYWdyZWVtZW50IGFuZCBwb2xhcml6YXRpb24gY2FsY3VsYXRpb24NCmxpYnJhcnkodmlzZGF0KSAjdmlzdWFsaXplIGRhdGFmcmFtZXMgaW4gcGxvdHMNCmxpYnJhcnkoUkNvbG9yQnJld2VyKSAjZWFzeSB0byB1c2UgY29sb3IgcGFsZXR0ZXMNCmxpYnJhcnkocm1hcmtkb3duKSAjZm9yIHRoZSBwYWdlZF90YWJsZSBmdW5jdGlvbg0KDQpsaWJyYXJ5KGRvUGFyYWxsZWwpICNwYXJhbGxlbCBjb21wdXRhdGlvbiB1c2luZyBtdWx0aXBsZSBjb3Jlcw0KbGlicmFyeShmb3JlYWNoKSAjIGZvciBlYWNoIGZ1bmN0aW9uLCBzbyB0aGUgc2ltdWxhdGlvbiBkb2VzIG5vdCB0YWtlIGFnZXMNCg0Kc2FtcGxlX3NlcXVlbmNlIDwtIGMoc2VxKDgwLDIwMCxieSA9MTApLCBzZXEoMzAwLDEwMDAsIGJ5ID0gMTAwKSkNCnNhbXBsZWQgPC0gZGF0YS5mcmFtZShOX3BhcnQgPSBzYW1wbGVfc2VxdWVuY2UpDQpyZXBsaWNhdGlvbnNfcGVyX3NldHRpbmcgPC0gNTANCg0KI3NldCBlY2hvID0gRkFMU0UgKGUuZy4gZG9udCBzaG93IGNvZGUgaW4gb3V0cHV0KSBmb3IgYWxsIGNodW5rcywgZXhjZXB0IHdoZW4gZXhwbGljaXRseSB0ZWxsaW5nIG90aGVyd2lzZQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KA0KICAgZWNobyA9IEZBTFNFLA0KICAgd2FybmluZyA9IFRSVUUsDQogICBtZXNzYWdlID0gVFJVRQ0KICAgKQ0KDQpgYGANCg0KIyBNZXRob2QgIA0KDQpUaGUgbWV0aG9kIGNob3NlbiBmb3IgdGhlIHNpbXVsYXRpb24gcHJvY2VkdXJlIGlzIGNhbGxlZCB0aGUgKipNb250ZSBDYXJsbyBzaW11bGF0aW9uKiouIEF0IGl0cyBjb3JlLCB0aGUgc2ltdWxhdGlvbiBjb25zaXN0cyBvZiByYW5kb20gc2FtcGxpbmcgYW5kIHN0YXRpc3RpY2FsIGFuYWx5c2lzLCBwcm92aWRlZCB0aGUgdW5kZXJseWluZyBzeXN0ZW0gY2FuIGJlIHJvdWdobHkgZXN0aW1hdGVkIG9yIGFwcHJveGltYXRlZCB3aXRoIHRoZSBzaW11bGF0aW9uIGl0c2VsZi4gQXMgdGhlIHByb2NlZHVyZSBsZXZlcmFnZXMgdGhlIGxhdyBvZiBsYXJnZSBudW1iZXJzLCB0aGUgcHJvY2VzcyB0YWtlcyBhIGxhcmdlIG51bWJlciBvZiByYW5kb20gc2FtcGxlcyBvZiBzYWlkIHN5c3RlbSB0byBzb2x2ZSBhIGNvbXBsZXggcHJvYmxlbS4gIA0KICANCiMjIFByb2JhYmlsaXR5IERpc3RyaWJ1dGlvbnMgIA0KDQpXZSB1c2Ugc2V2ZXJhbCBwcm9iYWJpbGl0eSBkaXN0cmlidXRpb25zIGFzIGEgcHJveHkgZm9yIHRoZSAidHJ1ZSIgZGlzdHJpYnV0aW9uIG9mIGRpZmZlcmVudCBraW5kcyBvZiByaXNrcyBpbiBhIGNlcnRhaW4gcG9wdWxhdGlvbi4gVXNpbmcgZGlmZmVyZW50IGRpc3RyaWJ1dGlvbnMgY2FuIGdpdmUgdXMgYSBiZXR0ZXIgaW5zaWdodCwgKiphc3N1bWluZyB0aGUgZGlzdHJpYnV0aW9uIGlzIGFsc28gcmVwcmVzZW50YXRpdmUgaW4gdGhlIHBvcHVsYXRpb24qKiB3ZSB3YW50IHRvIHNhbXBsZSBpbi4gIA0KDQpXaGlsZSBtb3N0IHRoaW5ncyBpbiBuYXR1cmUgaXMgbm9ybWFsbHkgZGlzdHJpYnV0ZWQsIHVzaW5nIHRoZSBiZXRhIGRpc3RyaWJ1dGlvbiB0byBpbGx1c3RyYXRlIGEgcG9sYXJpemVkIGRpc3RyaWJ1dGlvbiBpcyBhbHNvIHdhcnJhbnRlZC4gVGhlcmVmb3JlLCB0aGlzIHNpbXVsYXRpb24gdXNlcyBib3RoIG9mIHRoZXNlIGRpc3RyaWJ1dGlvbiB0eXBlcyBhcyBhIHByb3h5IGZvciBvdXIgcmlza3MuDQoNCmBgYHtyIFByb2JhYmlsaXR5IERpc3RyaWJ1dGlvbnMgaW4gUG9wdWxhdGlvbn0NCg0KcG9wdWxhdGlvbiA8LSAxMF41DQpwcm9wX21pbm9yaXR5IDwtIC4wMg0KDQojIENyZWF0ZSBhIGdyaWQgb2YgcGFyYW1ldGVycw0KYmV0YV9wYXJhbSA8LSBkYXRhLmZyYW1lKCBwYXJhbV8xID0gYyggMiwgLjEpLA0KICAgICAgICAgICAgcGFyYW1fMiA9IGMoLjYsIC4xKSkNCiMgc2V0IHRoZSBzZWVkLCBzbyBldmVyeXRoaW5nIGhlcmUgaXMgcmVwbGljYWJsZQ0Kc2V0LnNlZWQoNDIpDQoNCiMgR2VuZXJhdGUgcmFuZG9tIGRhdGEgZnJvbSBiZXRhIGRpc3RyaWJ1dGlvbnMgd2l0aCBkaWZmZXJlbnQgcGFyYW1ldGVycw0KZGF0YSA8LSBtYXAyKGJldGFfcGFyYW0kcGFyYW1fMSwgYmV0YV9wYXJhbSRwYXJhbV8yLCB+IHJiZXRhKHBvcHVsYXRpb24sIC54LCAueSkpDQoNCmRmIDwtIGFzLmRhdGEuZnJhbWUoZGF0YSkNCg0KY29sbmFtZXMoZGYpIDwtIDE6bnJvdyhiZXRhX3BhcmFtKQ0KZGYgPC0gYXMuZGF0YS5mcmFtZSh0KGRmKSkNCg0KI2NyZWF0ZSBub3JtYWwgZGlzdHJpYnV0aW9uLCBhbmQgYWRkaXRpb25hbGx5IG9uZSB3aGVyZSB3ZSBjb21iaW5lIGNvbWJpbmluZyAyIG5vcm1hbCBkaXN0cmlidXRpb25zDQpub3JtYWxfcGFyYSA8LSBkYXRhLmZyYW1lKHBhcmFtXzEgPSBjKC41LCAwKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1fMiA9IGMoLjE1LCAuMSkpDQoNCnBhcmFtZXRlcnMgPC0gcmJpbmQoYmV0YV9wYXJhbSwgbm9ybWFsX3BhcmEpDQoNCmFkZGl0aW9uYWxfcGFyYW0gPC0gZGF0YS5mcmFtZShwYXJhbV8zID0gYyhyZXAoMCxucm93KGJldGFfcGFyYW0pKSwgMCwgMSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1fNCA9IGMocmVwKDAsbnJvdyhiZXRhX3BhcmFtKSksIDAsIC4wMSkpDQoNCiNub3JtYWwgZGlzdHJpYnV0aW9uDQp2ZWMgPC0gYygpDQppID0gMQ0Kd2hpbGUgKGkgPD0gcG9wdWxhdGlvbil7DQogICBhID0gcm5vcm0oMSwgbWVhbiA9IG5vcm1hbF9wYXJhJHBhcmFtXzFbMV0sIHNkID0gbm9ybWFsX3BhcmEkcGFyYW1fMlsxXSkNCiAgIGlmIChhIDw9IDEgJiYgYSA+PSAwKXsNCiAgICAgIHZlY1tpXSA8LSBhDQogICAgICBpID0gaSArIDENCiAgIH0NCn0NCg0Kbm9ybWFsX2Rpc3RyIDwtIGFzLmRhdGEuZnJhbWUodCh2ZWMpKQ0KDQojY29tYmluZWQgbm9ybWFsIGRpc3RyaWJ1dGlvbg0KdmVjIDwtIGMoKQ0KaSA9IDENCndoaWxlIChpIDw9IHBvcHVsYXRpb24gKiAoMS0gcHJvcF9taW5vcml0eSkpew0KICAgYSA9IHJub3JtKDEsIG1lYW4gPSBwYXJhbWV0ZXJzJHBhcmFtXzFbbnJvdyhwYXJhbWV0ZXJzKV0sIHNkID0gcGFyYW1ldGVycyRwYXJhbV8yW25yb3cocGFyYW1ldGVycyldKQ0KICAgaWYgKGEgPj0gMCl7DQogICAgICB2ZWNbaV0gPC0gYQ0KICAgICAgaSA9IGkgKyAxDQogICB9DQp9DQoNCnZlYzEgPC0gYXMuZGF0YS5mcmFtZSh2ZWMpDQoNCnZlYyA8LSBjKCkNCmkgPSAxDQp3aGlsZSAoaSA8PSBwb3B1bGF0aW9uKiBwcm9wX21pbm9yaXR5KXsNCiAgIGEgPSBybm9ybSgxLCBtZWFuID0gYWRkaXRpb25hbF9wYXJhbSRwYXJhbV8zW25yb3coYWRkaXRpb25hbF9wYXJhbSldLCBzZCA9IGFkZGl0aW9uYWxfcGFyYW0kcGFyYW1fNFtucm93KGFkZGl0aW9uYWxfcGFyYW0pXSkNCiAgIGlmIChhIDw9IDEpew0KICAgICAgdmVjW2ldIDwtIGENCiAgICAgIGkgPSBpICsgMQ0KICAgfQ0KfQ0KDQp2ZWMyIDwtIGFzLmRhdGEuZnJhbWUodmVjKQ0KDQpjb21iaW5lZF9kaXN0ciA8LSBhcy5kYXRhLmZyYW1lKHQocmJpbmQodmVjMSx2ZWMyKSkpDQoNCg0KZGYgPC0gcmJpbmQoZGYsIG5vcm1hbF9kaXN0ciwgY29tYmluZWRfZGlzdHIpDQoNCiNzYXZlUkRTKGRmLCAiUG9wdWxhdGlvbl9kaXN0ci5yZHMiKQ0KDQojY3JlYXRlIHRoZSBkaWZmZXJlbnQgZnVuY3Rpb25zIHNvIHdlIGNhbiBjYWxjdWxhdGUgdGhlIHBvbGFyaXphdGlvbiBtZWFzdXJlcywgd2hpY2ggaXMgbmVlZGVkIGZvciB0aGUgbmV4dCBzdGVwDQpjYWxjdWxhdGVfc2tld25lc3MgPC0gZnVuY3Rpb24oY29sdW1uKSB7DQogICByZXN1bHQgPC0gZGVzY3JpYmUoY29sdW1uLCBza2V3ID0gVFJVRSkNCiAgIHJldHVybihyZXN1bHQkc2tldykNCn0NCg0KY2FsY3VsYXRlX2t1cnRvc2lzIDwtIGZ1bmN0aW9uKGNvbHVtbikgew0KICAgcmVzdWx0IDwtIGRlc2NyaWJlKGNvbHVtbikNCiAgIHJldHVybihyZXN1bHQka3VydG9zaSkNCn0NCg0KY2FsY3VsYXRlX24gPC0gZnVuY3Rpb24oY29sdW1uKSB7DQogICByZXN1bHQgPC0gIHN1bSghaXMubmEoY29sdW1uKSkNCn0NCg0KI2NhbGN1bGF0ZSBuZXcgdmVjdG9ycyBmb3IgZWFjaCByaXNrIGRpc3RyaWJ1dGlvbiwgYW5kIGFkZCB0aGVtIHRvIHRoZSBkYXRhZnJhbWUNCnNrZXc8LWFwcGx5KGRmLCAxLCAgY2FsY3VsYXRlX3NrZXduZXNzKQ0Ka3VydG9zaXMgPC0gYXBwbHkoZGYsIDEsIGNhbGN1bGF0ZV9rdXJ0b3NpcykNCg0KDQpkZjIgPC0gY2JpbmQocGFyYW1ldGVycywgYWRkaXRpb25hbF9wYXJhbSwgZGYsIHNrZXcsIGt1cnRvc2lzKSAgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgDQogICBwaXZvdF9sb25nZXIoY29scyA9IHN0YXJ0c193aXRoKCJWIiksIG5hbWVzX3RvID0gInZhcmlhbnQiLCB2YWx1ZXNfdG8gPSAidmFsdWVzIikgJT4lIA0KICAgbXV0YXRlKHBhcmFtXzEgPSBhcy5udW1lcmljKHBhcmFtXzEpLA0KICAgICAgICAgIHBhcmFtXzIgPSBhcy5udW1lcmljKHBhcmFtXzIpLA0KICAgICAgICAgIFBhcmFtZXRlcnMgPSBmYWN0b3IocGFzdGUocGFyYW1fMSwgcGFyYW1fMiwgc2VwID0gIi0iKSkpICU+JSANCiAgIGdyb3VwX2J5KHBhcmFtXzEscGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCkgJT4lIA0KICAgbXV0YXRlKG4gPSBuKCksDQogICAgICAgICAgSUQgPSBjdXJfZ3JvdXBfaWQoKSkNCg0KI2NhbGN1bGF0ZSB0aGUgYmltb2RpYWwgY29lZmZpY2llbnQgYWNjb3JkaW5nIHRvIEZpc2NoZXIgJiBGcmV5DQpkZjIgPC0gIGRmMiAlPiUgbXV0YXRlKGJpbW9kX2NvZWZmID0gKHNrZXdeMisxKS8gKGt1cnRvc2lzICsgKCgzKigobi0xKSleMikvKChuLTIpKihuLTMpKSkpKQ0KDQoNCkJDX2Fubm90YXRpb24gPC0gZGYyICU+JSANCiAgIGdyb3VwX2J5KHBhcmFtXzEscGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCkgJT4lIA0KICAgZGlzdGluY3QoUGFyYW1ldGVycyxiaW1vZF9jb2VmZikgJT4lIA0KICAgYXJyYW5nZShiaW1vZF9jb2VmZikNCg0KIyBjcmVhdGUgY29sb3IgdmVjdG9yLCBzbyBlYWNoIGNvbG9yIGlzIGVhc3kgdG8gZGlzdGluZ3Vpc2ggZm9yIHRob3NlIGdyb3Vwcw0KY29sb3JzIDwtIGJyZXdlci5wYWwoNCwgIkRhcmsyIikNCg0KZGYyJFBhcmFtZXRlcnMgPC0gcmVvcmRlcihkZjIkUGFyYW1ldGVycywgZGYyJGJpbW9kX2NvZWZmKQ0KDQoNCiNvcmRlciBpczogbm9ybWFsIGRpc3RyaWJ1dGlvbiBmaXJzdCwgdGhlbiBiZXRhIHNrZXdlZCwgbWl4ZWQsIHRoZW4gYmV0YSBzeW1tZXRyaWMNCiMgbGV2ZWxzKGRmMiRQYXJhbWV0ZXJzKQ0KDQojY3JlYXRlIHRoZSBwbG90DQpkZjIgJT4lIGdncGxvdChhZXModmFsdWVzLCBjb2wgPSBQYXJhbWV0ZXJzKSkrDQogICBnZW9tX2RlbnNpdHkobGluZXdpZHRoID0gMS4xKSArDQogICB0aGVtZV9taW5pbWFsKCkrDQogICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sb3JzKSsNCiAgIGFubm90YXRlKCJ0ZXh0IiwgeCA9IC41LCB5ID0gNywgY29sID0gY29sb3JzWzFdLCBzaXplID0gNiwgbGFiZWwgPSBzdHJfYygiTSA9ICIsQkNfYW5ub3RhdGlvbiRwYXJhbV8xWzFdLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiwgU0QgPSAiLCBCQ19hbm5vdGF0aW9uJHBhcmFtXzJbMV0sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLCBCQyA9ICIsIHJvdW5kKEJDX2Fubm90YXRpb24kYmltb2RfY29lZmZbMV0sIDIpKSkrDQogICBhbm5vdGF0ZSgidGV4dCIsIHg9IC41LCB5ID0gNixjb2wgPSBjb2xvcnNbM10sIHNpemUgPSA2LCBsYWJlbCA9IHN0cl9jKCJNID0gIiwgQkNfYW5ub3RhdGlvbiRwYXJhbV8xWzNdLCAiOyAiLCBCQ19hbm5vdGF0aW9uJHBhcmFtXzNbM10sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiwgU0QgPSAiLCBCQ19hbm5vdGF0aW9uJHBhcmFtXzJbM10sICI7ICIsIEJDX2Fubm90YXRpb24kcGFyYW1fNFszXSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLCBCQyA9ICIsIHJvdW5kKEJDX2Fubm90YXRpb24kYmltb2RfY29lZmZbM10sIDIpKSkrDQogICBhbm5vdGF0ZSgidGV4dCIsIHg9IC41LCB5ID0gNSxjb2wgPSBjb2xvcnNbMl0sIHNpemUgPSA2LCBsYWJlbCA9IHN0cl9jKCJBbHBoYSA9ICIsIEJDX2Fubm90YXRpb24kcGFyYW1fMVsyXSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLCAiICwiQmV0YSA9ICIsIEJDX2Fubm90YXRpb24kcGFyYW1fMlsyXSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLCAiLCAiQkMgPSAiLCByb3VuZChCQ19hbm5vdGF0aW9uJGJpbW9kX2NvZWZmWzJdLCAyKSkpKw0KICAgYW5ub3RhdGUoInRleHQiLCB4PSAuNSwgeSA9IDQgLGNvbCA9IGNvbG9yc1s0XSwgc2l6ZSA9IDYsIGxhYmVsID0gc3RyX2MoIkFscGhhID0gIiwgQkNfYW5ub3RhdGlvbiRwYXJhbV8xWzRdLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIsICIgLCJCZXRhID0gIiwgQkNfYW5ub3RhdGlvbiRwYXJhbV8yWzRdLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIsICIsICJCQyA9ICIsIHJvdW5kKEJDX2Fubm90YXRpb24kYmltb2RfY29lZmZbNF0sIDIpKSkrDQogICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpKw0KICAgeWxhYigiRGVuc2l0eSIpKw0KICAgeGxhYigiVmFsdWUiKQ0KDQpgYGANCg0KVG8gc2ltdWxhdGUgZGlmZmVyZW50IHR5cGVzIG9mIHJpc2sgYW5kIHRoZWlyIHBvc3NpYmxlIGRpc3RyaWJ1dGlvbnMsIHdlIGNob3NlIHR3byBiZXRhIGRpc3RyaWJ1dGlvbnMgKGEgWyoqc2tld2VkIGJldGEgZGlzdHJpYnV0aW9uKipde3N0eWxlPSJjb2xvcjogYHIgY29sb3JzWzJdYDsifSwgYW5kIGEgWyoqc3ltbWV0cmljYWwgYmV0YSBkaXN0cmlidXRpb24qKl17c3R5bGU9ImNvbG9yOiBgciBjb2xvcnNbNF1gOyJ9KSwgYSBbKipub3JtYWwgZGlzdHJpYnV0aW9uKipde3N0eWxlPSJjb2xvcjogYHIgY29sb3JzWzFdYDsifSwgYXMgd2VsbCBhcyBhIFsqKm1peGVkIGRpc3RyaWJ1dGlvbioqXXtzdHlsZT0iY29sb3I6IGByIGNvbG9yc1szXWA7In0gd2hpY2ggaXMgYnVpbHQgd2l0aCB0d28gdW5kZXJseWluZyBub3JtYWwgZGlzdHJpYnV0aW9ucyBpdHNlbGYuICANCiAgDQogIA0KV2hpbGUgdGhlIHR3byBiZXRhIGRpc3RyaWJ1dGlvbnMgc2hvdWxkIHNpbXVsYXRlIHJpc2tzIHRoYXQgYXJlIHBvbGFyaXplZCBpbiBkaWZmZXJlbnQgbWFubmVycywgdGhlIG5vcm1hbCBkaXN0cmlidXRpb24gaXMgYSBwcm94eSBmb3IgYSByaXNrIHdoZXJlIHRoZXJlIGlzIGEgY29uc2Vuc3VzIGluIHRoZSBwb3B1bGF0aW9uLiAgDQoNClRoZSBtaXhlZCBkaXN0cmlidXRpb24gdHJpZXMgdG8gY2FwdHVyZSB0aGUgZGlzdHJpYnV0aW9uIHdoZXJlIGEgbWlub3JpdHkgKGluIHRoaXMgY2FzZSB3aXRoIGEgYmFzZSByYXRlIG9mIGBgciBwcm9wX21pbm9yaXR5ICoxMDBgYCUpLCBoYXZlIGEgcG9sYXJpemluZyBvcGluaW9uIGNvbXBhcmVkIHRvIGEgbWFqb3JpdHkgaW4gYSBwb3B1bGF0aW9uLiAgDQoNCiMjIFRoZSBTaW11bGF0aW9uIFByb2NlZHVyZSAgDQoNCkZvciB0aGUgc2ltdWxhdGlvbiBpdHNlbGYsIHdlIHVzZSBgYHIgbnJvdyhzYW1wbGVkKWBgIGRpZmZlcmVudCBzYW1wbGUgc2l6ZXM6DQoNCmBgYHtyIFNob3cgc2FtcGxlIHNlcXVlbmNlfQ0Kc2FtcGxlX3NlcXVlbmNlDQpgYGANCg0KVXNpbmcgdGhlc2UgZGlmZmVyZW50IHNhbXBsZSBzaXplcywgd2Ugc2ltdWxhdGUgZm9yIGVhY2ggb2Ygb3VyIGBgciBucm93KEJDX2Fubm90YXRpb24pYGAgcmlzayBkaXN0cmlidXRpb25zLCBhbmQgcmVwbGljYXRlIHRoaXMgcHJvY2VkdXJlIGBgciByZXBsaWNhdGlvbnNfcGVyX3NldHRpbmdgYCB0aW1lcywgd2hpY2ggbGVhdmVzIHVzIHdpdGggYGByIG5yb3coc2FtcGxlZCkgKiBucm93KEJDX2Fubm90YXRpb24pICogcmVwbGljYXRpb25zX3Blcl9zZXR0aW5nYGAgc2ltdWxhdGlvbnMuXA0KVGhlIGdyb3VwZWQgZGlmZmVyZW5jZSBvZiB0aGVzZSBzYW1wbGVzIHNob3VsZCB0aGVuIGJlIGNvbXBhcmVkIGFnYWluc3QgdGhlIHBvbGFyaXphdGlvbiBtZWFzdXJlIG9mIHRoZSB3aG9sZSByaXNrIGRpc3RyaWJ1dGlvbiBpdHNlbGYsIHdoaWNoIGZ1bmN0aW9ucyBhcyBvdXIgInRydWUgc2NvcmUiLg0KDQpgYGB7ciBTaW11bGF0aW9uIFByb2NlZHVyZX0NCnNldC5zZWVkKDQyKQ0KDQptYXhfY29scyA8LSBtYXgoc2FtcGxlZCkgICANCg0KIyBSZWdpc3RlciBwYXJhbGxlbCBiYWNrZW5kIHdpdGggdGhlIGRlc2lyZWQgbnVtYmVyIG9mIGNvcmVzDQpudW1fY29yZXMgPC0gZGV0ZWN0Q29yZXMoKQ0KbnVtX2NvcmVzIDwtIGZsb29yKG51bV9jb3Jlcy8yKQ0KDQpjbCA8LSBtYWtlQ2x1c3RlcihudW1fY29yZXMpDQpyZWdpc3RlckRvUGFyYWxsZWwoY2wpDQoNCiMgRGVmaW5lIGZ1bmN0aW9uIHRvIHByb2Nlc3MgZWFjaCBjb21iaW5hdGlvbiBvZiByaXNrX2Rpc3RyaWJ1dGlvbiwgc2FtcGxlc2l6ZSBhbmQgcmVwbGljYXRpb25zIHBlciBzZXR0aW5nDQpzYW1wbGVfYW5kX3JlcGxpY2F0ZV9mb3JfYWxsX3Jpc2tzIDwtIGZ1bmN0aW9uKGkpIHsNCiAgc2FtcGxlZF9tYXRyaXhfbGlzdCA8LSBsaXN0KCkNCiAgDQogIGZvciAoaiBpbiAxOm5yb3coZGYpKSB7DQogICAgbWF0IDwtIHJlcGxpY2F0ZShyZXBsaWNhdGlvbnNfcGVyX3NldHRpbmcsDQogICAgICAgICAgICAgICAgICAgICBzYW1wbGUoMTpwb3B1bGF0aW9uLCBzaXplID0gc2FtcGxlZFtpLCAxXSwgcmVwbGFjZSA9IFRSVUUpKSAjY3JlYXRlIG1hdHJpeCBvZiBvdXIgc2FtcGxlcyB3aXRoIHJlcGxhY2luZywgdGltZXMgbiAtIHJlcGxpY2F0aW9ucw0KICAgIA0KICAgIHNhbXBsZWRfdGFibGUgPC0gZGZbaiwgbWF0XSAjdXNpbmcgdGhlIG1hdHJpeCwgY29sbGVjdCB0aGUgdmFsdWVzIGZyb20gb3VyIHJpc2sgZGlzdHJpYnV0aW9uIG1hdHJpeCAoYXMgYSB2ZWN0b3IgdGhvdWdoLi4uKQ0KICAgIHNhbXBsZWRfbWF0cml4IDwtIGFzLmRhdGEuZnJhbWUobWF0cml4KHNhbXBsZWRfdGFibGUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnJvdyA9IHJlcGxpY2F0aW9uc19wZXJfc2V0dGluZywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuY29sID0gc2FtcGxlZFtpLCAxXSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXJvdyA9IFRSVUUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGltbmFtZXMgPSBOVUxMKSkgI2NyZWF0ZSBkZiBvdXQgb2YgdGhlc2UgdmVjdG9ycyBpbnN0ZWFkIG9mIGZsYXQgdmVjdG9ycw0KICAgIA0KICAgIA0KICAgIGlmIChuY29sKHNhbXBsZWRfbWF0cml4KSA8IG1heF9jb2xzKSB7DQogICAgICBwYWRkaW5nX21hdHJpeCA8LSBtYXRyaXgoTkEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnJvdyA9IG5yb3coc2FtcGxlZF9tYXRyaXgpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5jb2wgPSBtYXhfY29scyAtIG5jb2woc2FtcGxlZF9tYXRyaXgpKQ0KICAgICAgc2FtcGxlZF9tYXRyaXggPC0gY2JpbmQoc2FtcGxlZF9tYXRyaXgsIHBhZGRpbmdfbWF0cml4KQ0KICAgIH0gI2lmIG1hdHJpeCBpcyBub3Qgd2lkZSBlbm91Z2ggZm9yIG91ciBlbmQgcmVzdWx0IG1hdHJpeCwgcGFkZCBpdCB3aXRoIE5BIGNvbHVtbnMsIHNvIGJpbmRpbmcgcm93cyBpcyBkb2FibGUgKG5lZWRzIHNhbWUgYW1vdW50IG9mIG5jb2xzKQ0KICAgIA0KICAgIHNhbXBsZWRfbWF0cml4IDwtIGNiaW5kKG1hdHJpeChzYW1wbGVkW2ksMV0sIG5yb3cgPSByZXBsaWNhdGlvbnNfcGVyX3NldHRpbmcpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRyaXgoaiwgbnJvdyA9IHJlcGxpY2F0aW9uc19wZXJfc2V0dGluZyksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2FtcGxlZF9tYXRyaXgpICNiaW5kIGNvbHVtbnMgd2l0aCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHN1Y2ggYXMgc2FtcGxlIHNpemUgYW5kIHdoaWNoIHJpc2tfZGlzdHJpYnV0aW9uIHdhcyBzYW1wbGVkDQogICAgDQogICAgY29sbmFtZXMoc2FtcGxlZF9tYXRyaXgpIDwtIGMoInNhbXBsZV9zaXplIiwgInJpc2tfZGlzdHJpYnV0aW9uIiwgcGFzdGUwKCJyYXRpbmdfIiwgMTptYXhfY29scykpICNyZXdyaXRlIGNvbG5hbWVzIHNvIGl0IGlzIGlkZW50aWNhbCB0byB0aGUgYmlnaCBtYXRyaXgNCiAgICBzYW1wbGVkX21hdHJpeF9saXN0W1tqXV0gPC0gc2FtcGxlZF9tYXRyaXggI3N0b3JlIGluIGxpc3QNCiAgfQ0KICByZXR1cm4oZG8uY2FsbChyYmluZCwgc2FtcGxlZF9tYXRyaXhfbGlzdCkpICNhZnRlciBhbGwgcmlzayBkaXN0cmlidXRpb25zIGFyZSBzYW1wbGVkIGZyb20sIGJpbmQgdGhlbSBhbGwgYW5kIHJldHVybiB0aGUgb3V0cHV0DQogIA0KfQ0KDQojIFBlcmZvcm0gcGFyYWxsZWwgcHJvY2Vzc2luZyB1c2luZyBmb3JlYWNoLCBpdGVyYXRpbmcgdGhyb3VnaCB0aGUgZGlmZmVyZW50IHNhbXBsZXNpemVzDQpyZXN1bHQgPC0gZm9yZWFjaChpID0gMTpucm93KHNhbXBsZWQpLCAuY29tYmluZSA9IHJiaW5kKSAlZG9wYXIlIHsNCiAgc2FtcGxlX2FuZF9yZXBsaWNhdGVfZm9yX2FsbF9yaXNrcyhpKQ0KfQ0KDQojIFN0b3AgdGhlIHBhcmFsbGVsIGJhY2tlbmQNCnN0b3BDbHVzdGVyKGNsKQ0KDQpyZXN1bHQgPC0gbXV0YXRlX2FsbChyZXN1bHQsIGFzLm51bWVyaWMgKQ0KDQpzbmlwcGVkX21hdHJpeCA8LSByZXN1bHRbLCBzZXEoNzIsMTAwMiwgYnk9IDIwKV0NCg0KdmlzX21pc3Moc25pcHBlZF9tYXRyaXgsIHNob3dfcGVyY19jb2wgPSBGKQ0KYGBgDQoNClRoZSBwbG90IGFib3ZlIHNob3dzIGEgc25pcHBlZCBvZiBvdXIgY3VycmVudCBtYXRyaXguIFRoZSBtYXRyaXggaGFzIGEgc3RhaXJjYXNlLWxpa2Ugc2hhcGUsIGFzIG5vdCBldmVyeSBzaW11bGF0aW9uIGhhcyAxMDAwIHJhdGluZ3MuIEZvciBleGFtcGxlLCB0aGUgZmlyc3QgZmV3IHJvd3MgY29udGFpbnMgb25seSBgYHIgc2FtcGxlZFsxLDFdYGAgcmF0aW5ncywgd2hlcmVhcyBhdCB0aGUgYm90dG9tIGVuZCwgd2UgaGF2ZSBgYHIgc2FtcGxlZFtucm93KHNhbXBsZWQpLDFdYGAgcmF0aW5ncy4gT3ZlcmFsbCwgdGhlIG1hdHJpeCBjb250YWlucyBgYHIgZGltKHJlc3VsdClbMV0gKiAoZGltKHJlc3VsdClbMl0tMikgLSBzdW0oaXMubmEocmVzdWx0KSlgYCByaXNrIHJhdGluZ3MuDQoNCldlIHVzZSB0aGlzIG1hdHJpeCB0byBjYWxjdWxhdGUgb3VyIHBvbGFyaXphdGlvbiBtZWFzdXJlcy4gU3RvcmluZyB0aGVzZSByaXNrIHJhdGluZ3MgaW4gb25lIGJpZyBtYXRyaXggKGV2ZW4gdGhvdWdoIGl0IGhhcyBtb3JlICJtaXNzaW5nIiB2YWx1ZXMpIGhlbHBzIHRvIGF2b2lkIGVycm9ycyBkb3duIHRoZSBsaW5lLCBhbmQgc3BlZWRzIHVwIHRoZSBjYWxjdWxhdGlvbiBhcyB3ZWxsLg0KDQpgYGB7ciBDYWxjdWxhdGUgUG9sYXJpemF0aW9uIE1lYXN1cmVzLCByZXN1bHRzPSdoaWRlJ30NCg0KI3NoYXBlIG91ciBwb3B1bGF0aW9uIGRhdGFmcmFtZSBzbyBpdCBpcyBlYXNpZXIgdG8gd29yayB3aXRoLCBhcyB3ZWxsIGFzIHR1cm4gdmFsdWVzIHRvIG51bWVyaWMsIHNvIHdlIGNhbiBzdGFydCB3aXRoIGNhbGN1bGF0aW9ucw0KZGYgPC0gdChkZikNCmNvbG5hbWVzKGRmKSA8LSBOVUxMDQpkZiA8LSBtdXRhdGVfYWxsKGFzLmRhdGEuZnJhbWUoZGYpLCBhcy5udW1lcmljKQ0KZGYgPC0gdChkZikNCg0KI3JvdW5kIG91ciBtYXRyaXggdG8gYSBjZXJ0YWluIGRpZ2l0LCBzbyB3ZSBoYXZlIHNvbWUgImRpc2NyZXRlIiBudW1iZXJzLCB3aGljaCBtYWtlcyBpdCBjb21wYXJhYmxlIHRvIG91ciBzdHVkeQ0KcmVzdWx0WywtYygxOjIpXSA8LSByb3VuZChyZXN1bHRbLC1jKDE6MildLCBkaWdpdHMgPSAyKQ0KDQoNCiNjcmVhdGluZyB0aGUgZnVuY3Rpb25zIGZvciBvdXIgcG9sYXJpemF0aW5vIG1lYXN1cmVtZW50cw0KDQpjYWxjX2Rpc3BlcnNpb24gPC0gZnVuY3Rpb24odmVjKXsNCiAgICAgIG1lZGlhbl92YWwgPC0gbWVkaWFuKHZlYywgbmEucm0gPSBUUlVFKQ0KICAgICAgYWJzX2RldmlhdGlvbiA8LSAgYWJzKHZlYyAtIG1lZGlhbl92YWwpDQogICAgICByZXR1cm4obWVkaWFuKGFic19kZXZpYXRpb24sIG5hLnJtID0gVFJVRSkpDQp9DQoNCmNhbGNfY292ZXJhZ2UgPC0gZnVuY3Rpb24odmVjLCByYW5nZSA9IDEsIG5faW50ZXJ2YWxzID0gMTApew0KDQogICBpbnRlcnZhbHMgPC0gcmFuZ2Uvbl9pbnRlcnZhbHMgKiBjKDA6bl9pbnRlcnZhbHMpDQogICB0b19zdW0gPC0gMA0KICAgTiA8LSAgc3VtKCFpcy5uYSh2ZWMpKQ0KICAgIyBDcmVhdGUgMTAgaW50ZXJ2YWxzIGZvciBlYWNoIHJvdw0KICAgIyBjb3ZlcmFnZXMgPC0gc2FwcGx5KHNlcV9hbG9uZyhpbnRlcnZhbHMpLCBmdW5jdGlvbihqKSB7DQogICAjICAgIHJvd19pbnRlcnZhbCA8LSBpbnRlcnZhbHNbal0NCiAgICMgICAgY291bnQgPC0gc3VtKGludGVydmFsc1tqXSA8PSB2ZWMgJiB2ZWMgPD0gaW50ZXJ2YWxzW2orMV0sIG5hLnJtID0gVCkNCiAgICMgfQ0KICAgIyApDQogICANCiAgIGNvdmVyYWdlcyA8LSB2ZWMgJT4lIA0KICAgICAgYXMubnVtZXJpYygpICU+JSANCiAgICAgIGN1dChicmVha3MgPSBpbnRlcnZhbHMsIGluY2x1ZGUubG93ZXN0ID0gVFJVRSkgJT4lIA0KICAgICAgdGFibGUoKSAlPiUgDQogICAgICBhcy5udW1lcmljKCkNCiAgIA0KICAgaWYgKHN1bShjb3ZlcmFnZXMsIG5hLnJtID0gVFJVRSkgIT0gTil7DQogICAgICByZXR1cm4oInN1bSBvZiBjb3ZlcmFnZXMgbm90IGVxdWFsIE4iKQ0KICAgfQ0KICAgZWxzZXsNCiAgICAgIGZvciAoaiBpbiAxOmxlbmd0aChjb3ZlcmFnZXMpKXsNCiAgICAgICAgIG4gPC0gY292ZXJhZ2VzW2pdDQogICAgICAgICB0b19zdW0gPC0gdG9fc3VtICsgKG4gKiAobi0xKSkNCiAgICAgIH0gDQogICB9DQogICByZXR1cm4oIDEtICh0b19zdW0gLyAoTiAqIChOLTEpKSkgKQ0KfQ0KDQpjYWxjX3NpemVfcGFyaXR5IDwtIGZ1bmN0aW9uKHZlYywgbWlkcG9pbnQgPSAuNSl7DQogICBOaGlnaCA8LSBzdW0odmVjID49IG1pZHBvaW50LCBuYS5ybSA9IFRSVUUpDQogICBObG93IDwtIHN1bSh2ZWMgPCBtaWRwb2ludCwgbmEucm0gPSBUUlVFKQ0KICAgTiA8LSBzdW0oIWlzLm5hKHZlYykpDQogICByZXR1cm4oYWJzKCAoTmhpZ2gvTikgLSAoTmxvdy9OKSkpDQp9DQoNCmNhbGNfZ3JvdXBfZGl2ZXJnZW5jZSA8LSBmdW5jdGlvbih2ZWMsIG1pZHBvaW50ID0gLjUsIHNjYWxlX3JhbmdlID0gMSl7DQogICANCiAgIFhfaGlnaCA8LSBtZWFuKHZlY1t2ZWMgPj0gbWlkcG9pbnRdLCBuYS5ybSA9IFRSVUUpDQogICBpZihzdW0odmVjW3ZlYyA+PSBtaWRwb2ludF0sIG5hLnJtID1UICkgPT0gMCl7DQogICAgICBYX2hpZ2ggPC0gMA0KICAgfQ0KICAgDQogICBYX2xvdyA8LSAgbWVhbih2ZWNbdmVjIDwgbWlkcG9pbnRdLCBuYS5ybSA9IFRSVUUpDQogICBpZihzdW0odmVjW3ZlYyA8IG1pZHBvaW50XSwgbmEucm0gPVQgKSA9PSAwKXsNCiAgICAgIFhfbG93IDwtIDANCiAgIH0NCiAgIHJldHVybigoYWJzKFhfaGlnaCAtIFhfbG93KS8gc2NhbGVfcmFuZ2UpKQ0KfQ0KDQpjYWxjX3BvbGFyaXphdGlvbl9pbmRleCA8LSBmdW5jdGlvbih2ZWMpew0KICAgUyA8LSBjYWxjX3NpemVfcGFyaXR5KHZlYykNCiAgIGQgPC0gY2FsY19ncm91cF9kaXZlcmdlbmNlKHZlYykNCiAgIHJldHVybiggKDEtUykqIGQpDQp9DQoNCmNhbGNfYmltb2RhbGl0eV9jb2VmZmljaWVudCA8LSBmdW5jdGlvbih2ZWMpew0KICAgc2tldyA8LSBza2V3KHZlYywgbmEucm0gPSBUUlVFLCB0eXBlID0gMykNCiAgIGt1cnRvc2lzIDwtIGt1cnRvc2kodmVjLCBuYS5ybSA9IFRSVUUsIHR5cGUgPSAzKQ0KICAgbiA8LSBzdW0oIWlzLm5hKHZlYykpDQogICByZXR1cm4oKHNrZXdeMisxKSAvIChrdXJ0b3NpcyArICgoMyooKG4tMSkpXjIpLygobi0yKSoobi0zKSkpICkpDQp9DQoNCg0KI25lZWRlZCBmb3IgdGhlIHBvbGFyaXphdGlvbiBtZWFzdXJlDQpjYWxjX29yZGVyZWRfZnJlcV92ZWMgPC0gZnVuY3Rpb24odmVjLCByYW5nZSA9IDEsIG5faW50ZXJ2YWxzID0gMTAwKXsNCiAgIA0KICAgaW50ZXJ2YWxzIDwtIHJhbmdlL25faW50ZXJ2YWxzICogYygwOm5faW50ZXJ2YWxzKQ0KICAgTiA8LSBzdW0oIWlzLm5hKHZlYykpDQogICAjZ2V0IG9yZGVyZWQgZnJlcXVlbmN5IHZlY3Rvciwgd2hpY2ggaXMgbmVlZGVkIGZvciB0aGUgbWFpbiBmdW5jdGlvbiwgYnV0IGZvcmVhY2ggYW5kIGRvcGFyIGRvZXMgbm90IHN1cHBvcnQgcGlwZXMsIHNvIEknbGwgaGF2ZSB0byB3cml0ZSBpdCBpbiBiYXNlIFIgc3ludGF4Li4uDQogICBvcmRlcmVkX2ZyZXFfdmVjIDwtDQogICAgICBhcy5udW1lcmljKHRhYmxlKGN1dChhcy5udW1lcmljKHZlYyksIGJyZWFrcyA9IGludGVydmFscywgaW5jbHVkZS5sb3dlc3QgPSBUUlVFKSkpDQogICANCiAgIGlmIChzdW0ob3JkZXJlZF9mcmVxX3ZlYywgbmEucm0gPSBUUlVFKSAhPSBOKXsNCiAgICAgIHJldHVybigic3VtIG9mIGNvdmVyYWdlcyBub3QgZXF1YWwgTiIpDQogICB9DQogICByZXR1cm4ob3JkZXJlZF9mcmVxX3ZlYykNCn0NCg0KDQojIGNhbGN1bGF0ZSBvdXIgbWVhc3VyZXMgb24gb3VyIHNhbXBsZXMsIGFzIHdlbGwgYXMgb24gb3VyIHBvcHVsYXRpb24gDQpkaXNwZXJzaW9uX3Jlc3VsdCA8LSBhcHBseShyZXN1bHRbLC0oMToyKV0sIDEsIGNhbGNfZGlzcGVyc2lvbikNCnN1bShpcy5uYShkaXNwZXJzaW9uX3Jlc3VsdCkpDQoNCmNvdmVyYWdlX3Jlc3VsdCA8LSBhcHBseShyZXN1bHRbLC0oMToyKV0sIDEsIGNhbGNfY292ZXJhZ2UpDQpjb3ZlcmFnZV9yZXN1bHQyIDwtIGFzLmludGVnZXIoY292ZXJhZ2VfcmVzdWx0KQ0Kc3VtKGlzLm5hKGNvdmVyYWdlX3Jlc3VsdCkpDQoNCnNpemVfcGFyaXR5X3Jlc3VsdCA8LSBhcHBseShyZXN1bHRbLC0oMToyKV0sIDEsIGNhbGNfc2l6ZV9wYXJpdHkpDQpzdW0oaXMubmEoc2l6ZV9wYXJpdHlfcmVzdWx0KSkNCg0KZ3JvdXBfZGl2ZXJnZW5jZV9yZXN1bHQgPC0gYXBwbHkocmVzdWx0WywtKDE6MildLCAxLCBjYWxjX2dyb3VwX2RpdmVyZ2VuY2UpDQpzdW0oaXMubmEoZ3JvdXBfZGl2ZXJnZW5jZV9yZXN1bHQpKQ0KDQpwb2xhcml6YXRpb25faW5kZXhfcmVzdWx0IDwtIGFwcGx5KHJlc3VsdFssLSgxOjIpXSwgMSwgY2FsY19wb2xhcml6YXRpb25faW5kZXgpDQpzdW0oaXMubmEocG9sYXJpemF0aW9uX2luZGV4X3Jlc3VsdCkpDQoNCkJDX3Jlc3VsdCA8LSBhcHBseShyZXN1bHRbLC0oMToyKV0sIDEsIGNhbGNfYmltb2RhbGl0eV9jb2VmZmljaWVudCkNCnN1bShpcy5uYShCQ19yZXN1bHQpKQ0KDQojYXMgdGhlIGNvbXB1dGF0aW9uIG9mIHBvbGFyaXNhdGlvbiBpcyByZWFsbHkgc3RyYWluaW5nIHdpdGggMTAwIGNhdGVnb3JpZXMsIHRoaXMgdG9vayBhcm91bmQgMzAgbWluIHRvIGNvbXB1dGUsIGV2ZW4gd2l0aCA2IGNvcmVzIGFuZCB3aGF0IEkgYmVsaWV2ZSB0byBiZSB0aGUgbW9zdCBlZmZpY2llbnQgd2F5IHBvc3NpYmxlIHRvIGNhbGN1bGF0ZS4gRm9yIHRoaXMgcmVhc29uLCBJJ3ZlIHNhdmVkIHRoZSByZXN1bHRzIHRvIGEgc2VwcGFyYXRlIFJEUyBmaWxlIHNvIGl0IGlzIGVhc2llciB0byBnZXQgYWNlc3MgdG8gaXQgd2l0aG91dCByZWNhbGN1bGF0aW5nIHRoaXMgcG9sYXJpc2F0aW9uIG1lYXN1cmUgYWdhaW4uDQoNCiMgY2wgPC0gbWFrZUNsdXN0ZXIoZGV0ZWN0Q29yZXMoKSkNCiMgcmVnaXN0ZXJEb1BhcmFsbGVsKGNsKQ0KIyANCiMgZnJlcV92ZWNfcmVzdWx0cyA8LSBmb3JlYWNoKGkgPSAxOm5yb3cocmVzdWx0KSwgLmNvbWJpbmUgPSByYmluZCkgJWRvcGFyJSB7DQojICAgY2FsY19vcmRlcmVkX2ZyZXFfdmVjKHJlc3VsdFtpLCAtYygxOjIpXSkNCiMgfQ0KIyANCiMgDQojIHBvbGFyaXphdGlvbl9yZXN1bHQgPC0gZm9yZWFjaChpID0gMTpucm93KGZyZXFfdmVjX3Jlc3VsdHMpLCAuY29tYmluZSA9IGMpICVkb3BhciUgew0KIyAgIGFncm10Ojpwb2xhcml6YXRpb24oZnJlcV92ZWNfcmVzdWx0c1tpLCBdKQ0KIyB9DQojIA0KIyBzdG9wQ2x1c3RlcihjbCkNCiMgDQojIA0KIyBzdW0oaXMubmEocG9sYXJpemF0aW9uX3Jlc3VsdCkpDQojIA0KIyBjb21iaW5lZF9yZXN1bHRfbWVhc3VyZXMgPC0gY2JpbmQocG9sYXJpemF0aW9uX3Jlc3VsdCwgDQojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNwZXJzaW9uX3Jlc3VsdCwNCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdmVyYWdlX3Jlc3VsdCwNCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfcGFyaXR5X3Jlc3VsdCwNCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwX2RpdmVyZ2VuY2VfcmVzdWx0LA0KIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9sYXJpemF0aW9uX2luZGV4X3Jlc3VsdCwNCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJDX3Jlc3VsdCwNCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdFssMToyXQ0KIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KI3NhdmVSRFMoY29tYmluZWRfcmVzdWx0X21lYXN1cmVzLCAiY2xlYW5lZF9kYXRhc2V0cy9jb21iaW5lZF9yZXN1bHRfbWVhc3VyZXMucmRzIikNCg0KY29tYmluZWRfcmVzdWx0X21lYXN1cmVzIDwtIHJlYWRfcmRzKCJjbGVhbmVkX2RhdGFzZXRzL2NvbWJpbmVkX3Jlc3VsdF9tZWFzdXJlcy5yZHMiKQ0KDQpzdW0oaXMubmEoY29tYmluZWRfcmVzdWx0X21lYXN1cmVzKSkNCg0KdmlzX21pc3MoY29tYmluZWRfcmVzdWx0X21lYXN1cmVzLCBzb3J0X21pc3MgPSBGKQ0KYGBgDQoNCmBgYHtyIENhbGN1bGF0ZSBUcnVlIFNjb3JlcyBpbiBvdXIgUG9wdWxhdGlvbiBEaXN0cmlidXRpb24sIHJlc3VsdHM9J2hpZGUnfQ0Kcmlza19kaXN0cmlidXRpb24gPC0gMTo0DQoNCnJpc2tfZGlzdHJpYnV0aW9uX3RyYW5zbCA8LSBjKCJCZXRhIDEgIiwgIkJldGEgMiIsICJOb3JtYWwiLCAiTWl4ZWQiKQ0KDQpkaXNwZXJzaW9uX3BvcHVsYXRpb24gPC0gYXBwbHkoZGYsIDEsIGNhbGNfZGlzcGVyc2lvbikNCnN1bShpcy5uYShkaXNwZXJzaW9uX3BvcHVsYXRpb24pKQ0KDQpjb3ZlcmFnZV9wb3B1bGF0aW9uIDwtIGFwcGx5KGRmLCAxLCBjYWxjX2NvdmVyYWdlKQ0Kc3VtKGlzLm5hKGNvdmVyYWdlX3BvcHVsYXRpb24pKQ0KDQpzaXplX3Bhcml0eV9wb3B1bGF0aW9uIDwtIGFwcGx5KGRmLCAxLCBjYWxjX3NpemVfcGFyaXR5KQ0Kc3VtKGlzLm5hKHNpemVfcGFyaXR5X3BvcHVsYXRpb24pKQ0KDQpncm91cF9kaXZlcmdlbmNlX3BvcHVsYXRpb24gPC0gYXBwbHkoZGYsIDEsIGNhbGNfZ3JvdXBfZGl2ZXJnZW5jZSkNCnN1bShpcy5uYShncm91cF9kaXZlcmdlbmNlX3BvcHVsYXRpb24pKQ0KDQpwb2xhcml6YXRpb25faW5kZXhfcG9wdWxhdGlvbiA8LSBhcHBseShkZiwgMSwgY2FsY19wb2xhcml6YXRpb25faW5kZXgpDQpzdW0oaXMubmEocG9sYXJpemF0aW9uX2luZGV4X3BvcHVsYXRpb24pKQ0KDQpCQ19wb3B1bGF0aW9uIDwtIGFwcGx5KGRmLCAxLCBjYWxjX2JpbW9kYWxpdHlfY29lZmZpY2llbnQpDQpzdW0oaXMubmEoQkNfcG9wdWxhdGlvbikpDQoNCg0KY2wgPC0gbWFrZUNsdXN0ZXIoZGV0ZWN0Q29yZXMoKSkNCnJlZ2lzdGVyRG9QYXJhbGxlbChjbCkNCg0KZnJlcV92ZWNfcmVzdWx0cyA8LSBmb3JlYWNoKGkgPSAxOm5yb3coZGYpLCAuY29tYmluZSA9IHJiaW5kKSAlZG9wYXIlIHsNCiAgY2FsY19vcmRlcmVkX2ZyZXFfdmVjKGRmW2ksXSkNCn0NCg0KDQpwb2xhcml6YXRpb25fcG9wdWxhdGlvbiA8LSBmb3JlYWNoKGkgPSAxOm5yb3coZnJlcV92ZWNfcmVzdWx0cyksIC5jb21iaW5lID0gYykgJWRvcGFyJSB7DQogIGFncm10Ojpwb2xhcml6YXRpb24oZnJlcV92ZWNfcmVzdWx0c1tpLCBdKQ0KfQ0KDQojcG9sYXJpemF0aW9uX3Jlc3VsdCA8LSBmb3JlYWNoKGkgPSAxOm5yb3cocmVzdWx0KSwgcmVzdWx0WywtKDE6MildLCAxLCBjYWxjX3BvbGFyaXphdGlvbikNCnN0b3BDbHVzdGVyKGNsKQ0KDQpjb21iaW5lZF9wb3B1bGF0aW9uX21lYXN1cmVzICA8LSBjYmluZChwb2xhcml6YXRpb25fcG9wdWxhdGlvbiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGVyc2lvbl9wb3B1bGF0aW9uLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdmVyYWdlX3BvcHVsYXRpb24sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV9wYXJpdHlfcG9wdWxhdGlvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cF9kaXZlcmdlbmNlX3BvcHVsYXRpb24sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9sYXJpemF0aW9uX2luZGV4X3BvcHVsYXRpb24sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQkNfcG9wdWxhdGlvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByaXNrX2Rpc3RyaWJ1dGlvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByaXNrX2Rpc3RyaWJ1dGlvbl90cmFuc2wNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApICU+JSANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzLmRhdGEuZnJhbWUoKSAlPiUgDQogICBtdXRhdGVfYXQoMTo4LCBhcy5udW1lcmljKQ0KDQpgYGANCg0KIyBSZXN1bHRzDQoNCiMjIE92ZXJhbGwgey50YWJzZXR9ICANCg0KIyMjIFBsb3QNCmBgYHtyIENvbWJpbmUgZXZlcnl0aGluZywgY2FsY3VsYXRlIGRpZmZlcmVuY2VzIGFuZCBwbG90LCB3YXJuaW5nID0gRkFMU0UsIGVycm9yPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KZmluYWxfY29tYmluYXRpb24gPC0gY29tYmluZWRfcmVzdWx0X21lYXN1cmVzICU+JSANCiAgIGZ1bGxfam9pbihjb21iaW5lZF9wb3B1bGF0aW9uX21lYXN1cmVzLCBieSA9ICJyaXNrX2Rpc3RyaWJ1dGlvbiIpICU+JSANCiAgIG11dGF0ZShkaWZmX1BvbGFyaXphdGlvbiA9IHBvbGFyaXphdGlvbl9wb3B1bGF0aW9uIC0gcG9sYXJpemF0aW9uX3Jlc3VsdCwNCiAgICAgICAgICBkaWZmX0Rpc3BlcnNpb24gPSBkaXNwZXJzaW9uX3BvcHVsYXRpb24gLSBkaXNwZXJzaW9uX3Jlc3VsdCwNCiAgICAgICAgICBkaWZmX0NvdmVyYWdlID0gY292ZXJhZ2VfcG9wdWxhdGlvbiAtIGNvdmVyYWdlX3Jlc3VsdCwNCiAgICAgICAgICBkaWZmX1NpemVfUGFyaXR5ID0gc2l6ZV9wYXJpdHlfcG9wdWxhdGlvbiAtIHNpemVfcGFyaXR5X3Jlc3VsdCwNCiAgICAgICAgICBkaWZmX0dyb3VwX0RpdmVyZ2VuY2UgPSBncm91cF9kaXZlcmdlbmNlX3BvcHVsYXRpb24gLSBncm91cF9kaXZlcmdlbmNlX3Jlc3VsdCwNCiAgICAgICAgICBkaWZmX1BvbGFyaXphdGlvbl9JbmRleCA9IHBvbGFyaXphdGlvbl9pbmRleF9wb3B1bGF0aW9uIC0gcG9sYXJpemF0aW9uX2luZGV4X3Jlc3VsdCwNCiAgICAgICAgICBkaWZmX0JDID0gQkNfcG9wdWxhdGlvbiAtIEJDX3Jlc3VsdCkNCg0KI3N1bShpcy5uYShmaW5hbF9jb21iaW5hdGlvbikpDQoNCmZpbmFsX2NvbWJpbmF0aW9uX2xvbmcgPC0gZmluYWxfY29tYmluYXRpb24gJT4lDQogICBzZWxlY3Qoc2FtcGxlX3NpemUsIHJpc2tfZGlzdHJpYnV0aW9uLCBjb250YWlucygiZGlmZl8iKSwgcmlza19kaXN0cmlidXRpb25fdHJhbnNsKSAlPiUgDQogICBwaXZvdF9sb25nZXIoY29udGFpbnMoImRpZmZfIiksIG5hbWVzX3RvID0gIk1lYXN1cmVtZW50IixuYW1lc19wcmVmaXggPSAiZGlmZl8iLCAgdmFsdWVzX3RvID0gIkRpZmZlcmVuY2UiKQ0KDQpmaW5hbF9zdW1tYXJpemVkX3RhYmxlIDwtIGZpbmFsX2NvbWJpbmF0aW9uX2xvbmcgJT4lDQogICBncm91cF9ieShyaXNrX2Rpc3RyaWJ1dGlvbiwgcmlza19kaXN0cmlidXRpb25fdHJhbnNsLCBzYW1wbGVfc2l6ZSwgTWVhc3VyZW1lbnQpICU+JSANCiAgIHN1bW1hcmlzZSgnTWVhbiBEaWZmZXJlbmNlJyA9IG1lYW4oRGlmZmVyZW5jZSksDQogICAgICAgICAgICAgJ1NEIERpZmZlcmVuY2UnID0gc2QoRGlmZmVyZW5jZSksDQogICAgICAgICAgICAgJ01pbiBEaWZmZXJlbmNlJyA9IG1pbihEaWZmZXJlbmNlKSwNCiAgICAgICAgICAgICAnTWF4IERpZmZlcmVuY2UnID0gbWF4KERpZmZlcmVuY2UpKSAlPiUgDQogICB1bmdyb3VwKCkgJT4lIA0KICAgbXV0YXRlKGZzYW1wbGVfc2l6ZSA9IGZhY3RvcihzYW1wbGVfc2l6ZSwgb3JkZXJlZCA9IFRSVUUpKQ0KDQoNCg0KI3Jlb3JkZXIgc28gZWFjaCBvbmUgZ2V0cyB0aGVpciBvd24gY29sb3IgYWdhaW46DQojb3JkZXIgaXM6IG5vcm1hbCBkaXN0cmlidXRpb24gZmlyc3QsIHRoZW4gYmV0YSBza2V3ZWQsIG1peGVkLCB0aGVuIGJldGEgc3ltbWV0cmljDQpmaW5hbF9zdW1tYXJpemVkX3RhYmxlJHJpc2tfZGlzdHJpYnV0aW9uX3RyYW5zbCA8LSBmYWN0b3IoZmluYWxfc3VtbWFyaXplZF90YWJsZSRyaXNrX2Rpc3RyaWJ1dGlvbl90cmFuc2wsIGxldmVscyA9IGMoIk5vcm1hbCIsICJCZXRhIDEgIiwgIk1peGVkIiwgIkJldGEgMiIpLCBsYWJlbHMgPSBjKCJOb3JtYWwiLCAiU2tld2VkIEJldGEiLCAiTWl4ZWQiLCAiU3ltbWV0cmljIEJldGEiKSkNCiAgIA0KZmluYWxfc3VtbWFyaXplZF90YWJsZSAlPiUgDQogICBnZ3Bsb3QoYWVzKGZzYW1wbGVfc2l6ZSwgYE1lYW4gRGlmZmVyZW5jZWAsIGNvbCA9IHJpc2tfZGlzdHJpYnV0aW9uX3RyYW5zbCwgZ3JvdXAgPSByaXNrX2Rpc3RyaWJ1dGlvbl90cmFuc2wpKSsNCiAgIGdlb21fbGluZSgpKw0KICAgZ2VvbV9wb2ludChzaXplID0gMiwgYWxwaGEgPSAuOCkrDQogICBmYWNldF9ncmlkKHJvd3MgPSB2YXJzKE1lYXN1cmVtZW50KSkrDQogICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sb3JzKSsNCiAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAgLCBjb2w9ImJsYWNrIiwgbGluZXR5cGU9ICJkYXNoZWQiLCBsaW5ld2lkdGggPSAuOSwgYWxwaGEgPSAuOCkrDQogICB0aGVtZV9taW5pbWFsKCkrDQogICB4bGFiKCJTYW1wbGUgU2l6ZSIpKw0KICAgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKQ0KYGBgDQoNCiMjIyBQb2xhcml6YXRpb24gbWVhc3VyZXMgaW4gb3VyIHBvcHVsYXRpb24gZGlzdHJpYnV0aW9uIHsuYWN0aXZlfSAgDQoNCmBgYHtyfQ0KY29tYmluZWRfcG9wdWxhdGlvbl9tZWFzdXJlczIgPC0gY29tYmluZWRfcG9wdWxhdGlvbl9tZWFzdXJlcw0KY29tYmluZWRfcG9wdWxhdGlvbl9tZWFzdXJlczIkcmlza19kaXN0cmlidXRpb25fdHJhbnNsIDwtIGMoIlNrZXdlZCBCZXRhIiwgIlN5bW1ldHJpYyBCZXRhIiwgIk5vcm1hbCIsICJNaXhlZCIpDQpjb21iaW5lZF9wb3B1bGF0aW9uX21lYXN1cmVzMiAlPiUgDQogICBzZWxlY3QoMTo3LDkpICU+JSANCiAgICNtdXRhdGVfYXQoMTo3LCAuZnVucyA9IH5yb3VuZCguLCBkaWdpdHMgPSAzKSklPiUgDQogICBrYWJsZShmb3JtYXQgPSAiaHRtbCIsIA0KICAgICAgICAgY2FwdGlvbiA9ICJUcnVlIFNjb3JlIFRhYmxlIiwgDQogICAgICAgICBkaWdpdHMgPSAzLCANCiAgICAgICAgIGNvbC5uYW1lcyA9IGMoIlBvbGFyaXphdGlvbiIsICJEaXNwZXJzaW9uIiwgIkNvdmVyYWdlIiwgIlNpemUgUGFyaXR5IiwgIkdyb3VwIERpdmVyZ2VuY2UiLCAiUG9sYXJpemF0aW9uIEluZGV4IiwgIkJpbW9kYWxpdHkgQ29lZmZpY2llbnQiLCAiUmlzayBEaXN0cmlidXRpb24iKSwgDQogICAgICAgICBhbGlnbiA9ICJjIiwNCiAgICAgICAgIHJvdy5uYW1lcyA9IEZBTFNFKSAlPiUgDQogICBrYWJsZUV4dHJhOjpyb3dfc3BlYyhyb3cgPSAwLCBhbmdsZSA9IC0yNSkNCg0KYGBgDQoNCg0KIyMgQmltb2RhbGl0eSBDb2VmZmljaWVudCB7LnRhYnNldH0NCg0KIyMjIFBsb3QNCg0KYGBge3IgQmltb2RhbGl0eSBDb2VmZmljaWVudH0NCg0KDQpzcGxpdHRlZF9zdW1tYXJ5IDwtIHNwbGl0KGZpbmFsX3N1bW1hcml6ZWRfdGFibGUsIGZpbmFsX3N1bW1hcml6ZWRfdGFibGUkTWVhc3VyZW1lbnQpDQoNCmZvciAoY2F0ZWdvcnlfbmFtZSBpbiBuYW1lcyhzcGxpdHRlZF9zdW1tYXJ5KSkgew0KICBhc3NpZ24ocGFzdGUwKCJkZl8iLCBjYXRlZ29yeV9uYW1lKSwgc3BsaXR0ZWRfc3VtbWFyeVtbY2F0ZWdvcnlfbmFtZV1dKQ0KfQ0KDQoNCmNvbF90b190YWtlX2Zvcl90YWJsZSA8LSBjKDIsMyw1OjgpDQoNCg0KZGZfQkMgJT4lIA0KICAgbXV0YXRlKHltaW4gPSBgTWVhbiBEaWZmZXJlbmNlYC0gYFNEIERpZmZlcmVuY2VgLA0KICAgICAgICAgICAgICAgICB5bWF4ID0gYE1lYW4gRGlmZmVyZW5jZWAgKyBgU0QgRGlmZmVyZW5jZWApICU+JSANCiAgIGdncGxvdChhZXMoZnNhbXBsZV9zaXplLCBgTWVhbiBEaWZmZXJlbmNlYCwgZ3JvdXAgPSByaXNrX2Rpc3RyaWJ1dGlvbl90cmFuc2wsIGNvbCA9IHJpc2tfZGlzdHJpYnV0aW9uX3RyYW5zbCkpKw0KICAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDEuMDUpKw0KICAgZ2VvbV9wb2ludChzaXplID0gMS44KSsNCiAgIHRoZW1lX2J3KCkrDQogICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sb3JzKSsNCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgIGxlZ2VuZC5kaXJlY3Rpb24gPSAiaG9yaXpvbnRhbCIsDQogICAgICAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgI3N0cmlwLnBsYWNlbWVudCA9ICJ0b3AiLA0KICAgICAgICAgbGVnZW5kLmtleS5zaXplID0gdW5pdCgyLjQsICJsaW5lcyIpLA0KICAgICAgICAgbGVnZW5kLmtleSA9IGVsZW1lbnRfcmVjdChmaWxsID0gInRyYW5zcGFyZW50IiksDQogICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNC41KSkrDQogICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwICwgY29sPSJibGFjayIsIGxpbmV0eXBlPSAiZGFzaGVkIiwgbGluZXdpZHRoID0gMS4xKSsNCiAgIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSB5bWluLCB5bWF4ID0geW1heCwgd2lkdGggPSAuMikpICsNCiAgIGZhY2V0X2dyaWQocm93cyA9IHZhcnMocmlza19kaXN0cmlidXRpb25fdHJhbnNsKSApKw0KICAgeGxhYigiU2FtcGxlIFNpemUiKSsNCiAgIHlsYWIoJ0RpZmZlcmVuY2UgdG8gIlRydWUiIFNjb3JlJykrDQogICAjc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoLS4xLCAtMC41LCAwLCAuMDUsIC4xLCAuMTUsIC4yKSkNCiAgICNhbm5vdGF0ZSgidGV4dCIsIHggPSBsZW5ndGgoc2FtcGxlX3NlcXVlbmNlKS8yLCB5ID0uMiAsIGNvbG9yID0gY29sb3JzWzFdLCBsYWJlbCA9IHVuaXF1ZShyaXNrX2Rpc3RyaWJ1dGlvbl90cmFuc2xbMV0pKQ0KICAgZ2VvbV90ZXh0KGFlcyh4ID1sZW5ndGgoc2FtcGxlX3NlcXVlbmNlKS8yLCB5ID0gcXVhbnRpbGUoeW1heCwgcHJvYnMgPS44NSkrLjEsIGxhYmVsID0gcmlza19kaXN0cmlidXRpb25fdHJhbnNsKSwgc2l6ZSA9IDYuNSkrDQogICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtLjEsIC4yNSkpDQogICANCg0KYGBgDQoNCiMjIyBUYWJsZQ0KDQpgYGB7cn0NCmRmX0JDWyxjb2xfdG9fdGFrZV9mb3JfdGFibGVdICU+JSANCiAgIG11dGF0ZV9hdCgzOjYsIC5mdW5zID0gfnJvdW5kKC4sIGRpZ2l0cyA9IDMpKSU+JSANCiAgIHBhZ2VkX3RhYmxlKG9wdGlvbnMgPSBsaXN0KHJvd25hbWVzLnByaW50ID0gRiwgcm93cy5wcmludCA9IGxlbmd0aChzYW1wbGVfc2VxdWVuY2UpKSkNCmBgYA0KDQojIyBQb2xhcml6YXRpb24gey50YWJzZXR9DQoNCiMjIyBQbG90DQoNCmBgYHtyfQ0KZGZfUG9sYXJpemF0aW9uICU+JSANCiAgIG11dGF0ZSh5bWluID0gYE1lYW4gRGlmZmVyZW5jZWAtIGBTRCBEaWZmZXJlbmNlYCwNCiAgICAgICAgICB5bWF4ID0gYE1lYW4gRGlmZmVyZW5jZWAgKyBgU0QgRGlmZmVyZW5jZWApICU+JSANCiAgIGdncGxvdChhZXMoZnNhbXBsZV9zaXplLCBgTWVhbiBEaWZmZXJlbmNlYCwgZ3JvdXAgPSByaXNrX2Rpc3RyaWJ1dGlvbl90cmFuc2wsIGNvbCA9IHJpc2tfZGlzdHJpYnV0aW9uX3RyYW5zbCkpKw0KICAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDEuMDUpKw0KICAgZ2VvbV9wb2ludChzaXplID0gMS44KSsNCiAgIHRoZW1lX2J3KCkrDQogICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sb3JzKSsNCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgIGxlZ2VuZC5kaXJlY3Rpb24gPSAiaG9yaXpvbnRhbCIsDQogICAgICAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgI3N0cmlwLnBsYWNlbWVudCA9ICJ0b3AiLA0KICAgICAgICAgbGVnZW5kLmtleS5zaXplID0gdW5pdCgyLjQsICJsaW5lcyIpLA0KICAgICAgICAgbGVnZW5kLmtleSA9IGVsZW1lbnRfcmVjdChmaWxsID0gInRyYW5zcGFyZW50IiksDQogICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNC41KSkrDQogICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwICwgY29sPSJibGFjayIsIGxpbmV0eXBlPSAiZGFzaGVkIiwgbGluZXdpZHRoID0gMS4xKSsNCiAgIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSB5bWluLCB5bWF4ID0geW1heCwgd2lkdGggPSAuMikpICsNCiAgIGZhY2V0X2dyaWQocm93cyA9IHZhcnMocmlza19kaXN0cmlidXRpb25fdHJhbnNsKSApKw0KICAgeGxhYigiU2FtcGxlIFNpemUiKSsNCiAgIHlsYWIoJ0RpZmZlcmVuY2UgdG8gIlRydWUiIFNjb3JlJykrDQogICAjc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoLS4xLCAtMC41LCAwLCAuMDUsIC4xLCAuMTUsIC4yKSkNCiAgICNhbm5vdGF0ZSgidGV4dCIsIHggPSBsZW5ndGgoc2FtcGxlX3NlcXVlbmNlKS8yLCB5ID0uMiAsIGNvbG9yID0gY29sb3JzWzFdLCBsYWJlbCA9IHVuaXF1ZShyaXNrX2Rpc3RyaWJ1dGlvbl90cmFuc2xbMV0pKQ0KICAgZ2VvbV90ZXh0KGFlcyh4ID1sZW5ndGgoc2FtcGxlX3NlcXVlbmNlKS8yLCB5ID0gcXVhbnRpbGUoeW1heCwgcHJvYnMgPS44NSkrLjEsIGxhYmVsID0gcmlza19kaXN0cmlidXRpb25fdHJhbnNsKSwgc2l6ZSA9IDYuNSkrDQogICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtLjA1LCAuMjUpKQ0KYGBgDQoNCiMjIyBUYWJsZQ0KDQpgYGB7cn0NCmRmX1BvbGFyaXphdGlvblssY29sX3RvX3Rha2VfZm9yX3RhYmxlXSAlPiUgDQogICBtdXRhdGVfYXQoMzo2LCAuZnVucyA9IH5yb3VuZCguLCBkaWdpdHMgPSAzKSklPiUNCiAgIHBhZ2VkX3RhYmxlKG9wdGlvbnMgPSBsaXN0KHJvd25hbWVzLnByaW50ID0gRiwgcm93cy5wcmludCA9IGxlbmd0aChzYW1wbGVfc2VxdWVuY2UpKSkNCmBgYA0KDQojIyBDb3ZlcmFnZSB7LnRhYnNldH0NCg0KIyMjIFBsb3QNCg0KYGBge3J9DQpkZl9Db3ZlcmFnZSAlPiUgDQogICBtdXRhdGUoeW1pbiA9IGBNZWFuIERpZmZlcmVuY2VgLSBgU0QgRGlmZmVyZW5jZWAsDQogICAgICAgICAgeW1heCA9IGBNZWFuIERpZmZlcmVuY2VgICsgYFNEIERpZmZlcmVuY2VgKSAlPiUgDQogICBnZ3Bsb3QoYWVzKGZzYW1wbGVfc2l6ZSwgYE1lYW4gRGlmZmVyZW5jZWAsIGdyb3VwID0gcmlza19kaXN0cmlidXRpb25fdHJhbnNsLCBjb2wgPSByaXNrX2Rpc3RyaWJ1dGlvbl90cmFuc2wpKSsNCiAgIGdlb21fbGluZShsaW5ld2lkdGggPSAxLjA1KSsNCiAgIGdlb21fcG9pbnQoc2l6ZSA9IDEuOCkrDQogICB0aGVtZV9idygpKw0KICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbG9ycykrDQogICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICBsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiLA0KICAgICAgICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICNzdHJpcC5wbGFjZW1lbnQgPSAidG9wIiwNCiAgICAgICAgIGxlZ2VuZC5rZXkuc2l6ZSA9IHVuaXQoMi40LCAibGluZXMiKSwNCiAgICAgICAgIGxlZ2VuZC5rZXkgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ0cmFuc3BhcmVudCIpLA0KICAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQuNSkpKw0KICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCAsIGNvbD0iYmxhY2siLCBsaW5ldHlwZT0gImRhc2hlZCIsIGxpbmV3aWR0aCA9IDEuMSkrDQogICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0geW1pbiwgeW1heCA9IHltYXgsIHdpZHRoID0gLjIpKSArDQogICBmYWNldF9ncmlkKHJvd3MgPSB2YXJzKHJpc2tfZGlzdHJpYnV0aW9uX3RyYW5zbCkgKSsNCiAgIHhsYWIoIlNhbXBsZSBTaXplIikrDQogICB5bGFiKCdEaWZmZXJlbmNlIHRvICJUcnVlIiBTY29yZScpKw0KICAgI3NjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKC0uMSwgLTAuNSwgMCwgLjA1LCAuMSwgLjE1LCAuMikpDQogICAjYW5ub3RhdGUoInRleHQiLCB4ID0gbGVuZ3RoKHNhbXBsZV9zZXF1ZW5jZSkvMiwgeSA9LjIgLCBjb2xvciA9IGNvbG9yc1sxXSwgbGFiZWwgPSB1bmlxdWUocmlza19kaXN0cmlidXRpb25fdHJhbnNsWzFdKSkNCiAgIGdlb21fdGV4dChhZXMoeCA9bGVuZ3RoKHNhbXBsZV9zZXF1ZW5jZSkvMiwgeSA9IHF1YW50aWxlKHltYXgsIHByb2JzID0uODUpKy4xLCBsYWJlbCA9IHJpc2tfZGlzdHJpYnV0aW9uX3RyYW5zbCksIHNpemUgPSA2LjUpKw0KICAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLS4xLCAuMikpDQpgYGANCg0KIyMjIFRhYmxlDQoNCmBgYHtyfQ0KZGZfQ292ZXJhZ2VbLGNvbF90b190YWtlX2Zvcl90YWJsZV0gJT4lIA0KICAgbXV0YXRlX2F0KDM6NiwgLmZ1bnMgPSB+cm91bmQoLiwgZGlnaXRzID0gMykpJT4lDQogICBwYWdlZF90YWJsZShvcHRpb25zID0gbGlzdChyb3duYW1lcy5wcmludCA9IEYsIHJvd3MucHJpbnQgPSBsZW5ndGgoc2FtcGxlX3NlcXVlbmNlKSkpDQpgYGANCg0KIyMgRGlzcGVyc2lvbiB7LnRhYnNldH0NCg0KIyMjIFBsb3QNCg0KYGBge3J9DQpkZl9EaXNwZXJzaW9uICU+JSANCiAgIG11dGF0ZSh5bWluID0gYE1lYW4gRGlmZmVyZW5jZWAtIGBTRCBEaWZmZXJlbmNlYCwNCiAgICAgICAgICB5bWF4ID0gYE1lYW4gRGlmZmVyZW5jZWAgKyBgU0QgRGlmZmVyZW5jZWApICU+JSANCiAgIGdncGxvdChhZXMoZnNhbXBsZV9zaXplLCBgTWVhbiBEaWZmZXJlbmNlYCwgZ3JvdXAgPSByaXNrX2Rpc3RyaWJ1dGlvbl90cmFuc2wsIGNvbCA9IHJpc2tfZGlzdHJpYnV0aW9uX3RyYW5zbCkpKw0KICAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDEuMDUpKw0KICAgZ2VvbV9wb2ludChzaXplID0gMS44KSsNCiAgIHRoZW1lX2J3KCkrDQogICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sb3JzKSsNCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgIGxlZ2VuZC5kaXJlY3Rpb24gPSAiaG9yaXpvbnRhbCIsDQogICAgICAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgI3N0cmlwLnBsYWNlbWVudCA9ICJ0b3AiLA0KICAgICAgICAgbGVnZW5kLmtleS5zaXplID0gdW5pdCgyLjQsICJsaW5lcyIpLA0KICAgICAgICAgbGVnZW5kLmtleSA9IGVsZW1lbnRfcmVjdChmaWxsID0gInRyYW5zcGFyZW50IiksDQogICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNC41KSkrDQogICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwICwgY29sPSJibGFjayIsIGxpbmV0eXBlPSAiZGFzaGVkIiwgbGluZXdpZHRoID0gMS4xKSsNCiAgIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSB5bWluLCB5bWF4ID0geW1heCwgd2lkdGggPSAuMikpICsNCiAgIGZhY2V0X2dyaWQocm93cyA9IHZhcnMocmlza19kaXN0cmlidXRpb25fdHJhbnNsKSApKw0KICAgeGxhYigiU2FtcGxlIFNpemUiKSsNCiAgIHlsYWIoJ0RpZmZlcmVuY2UgdG8gIlRydWUiIFNjb3JlJykrDQogICAjc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoLS4xLCAtMC41LCAwLCAuMDUsIC4xLCAuMTUsIC4yKSkNCiAgICNhbm5vdGF0ZSgidGV4dCIsIHggPSBsZW5ndGgoc2FtcGxlX3NlcXVlbmNlKS8yLCB5ID0uMiAsIGNvbG9yID0gY29sb3JzWzFdLCBsYWJlbCA9IHVuaXF1ZShyaXNrX2Rpc3RyaWJ1dGlvbl90cmFuc2xbMV0pKQ0KICAgZ2VvbV90ZXh0KGFlcyh4ID1sZW5ndGgoc2FtcGxlX3NlcXVlbmNlKS8yLCB5ID0gcXVhbnRpbGUoeW1heCwgcHJvYnMgPS44NSkrLjEzLCBsYWJlbCA9IHJpc2tfZGlzdHJpYnV0aW9uX3RyYW5zbCksIHNpemUgPSA2LjUpKw0KICAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLS4wNSwgLjM1KSkNCmBgYA0KDQojIyMgVGFibGUNCg0KYGBge3J9DQpkZl9EaXNwZXJzaW9uWyxjb2xfdG9fdGFrZV9mb3JfdGFibGVdICU+JSANCiAgIG11dGF0ZV9hdCgzOjYsIC5mdW5zID0gfnJvdW5kKC4sIGRpZ2l0cyA9IDMpKSU+JQ0KICAgcGFnZWRfdGFibGUob3B0aW9ucyA9IGxpc3Qocm93bmFtZXMucHJpbnQgPSBGLCByb3dzLnByaW50ID0gbGVuZ3RoKHNhbXBsZV9zZXF1ZW5jZSkpKQ0KYGBgDQoNCiMjIEdyb3VwIERpdmVyZ2VuY2Ugey50YWJzZXR9DQoNCiMjIyBQbG90DQoNCmBgYHtyfQ0KZGZfR3JvdXBfRGl2ZXJnZW5jZSAlPiUgDQogICBtdXRhdGUoeW1pbiA9IGBNZWFuIERpZmZlcmVuY2VgLSBgU0QgRGlmZmVyZW5jZWAsDQogICAgICAgICAgeW1heCA9IGBNZWFuIERpZmZlcmVuY2VgICsgYFNEIERpZmZlcmVuY2VgKSAlPiUgDQogICBnZ3Bsb3QoYWVzKGZzYW1wbGVfc2l6ZSwgYE1lYW4gRGlmZmVyZW5jZWAsIGdyb3VwID0gcmlza19kaXN0cmlidXRpb25fdHJhbnNsLCBjb2wgPSByaXNrX2Rpc3RyaWJ1dGlvbl90cmFuc2wpKSsNCiAgIGdlb21fbGluZShsaW5ld2lkdGggPSAxLjA1KSsNCiAgIGdlb21fcG9pbnQoc2l6ZSA9IDEuOCkrDQogICB0aGVtZV9idygpKw0KICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbG9ycykrDQogICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICBsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiLA0KICAgICAgICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICNzdHJpcC5wbGFjZW1lbnQgPSAidG9wIiwNCiAgICAgICAgIGxlZ2VuZC5rZXkuc2l6ZSA9IHVuaXQoMi40LCAibGluZXMiKSwNCiAgICAgICAgIGxlZ2VuZC5rZXkgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ0cmFuc3BhcmVudCIpLA0KICAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQuNSkpKw0KICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCAsIGNvbD0iYmxhY2siLCBsaW5ldHlwZT0gImRhc2hlZCIsIGxpbmV3aWR0aCA9IDEuMSkrDQogICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0geW1pbiwgeW1heCA9IHltYXgsIHdpZHRoID0gLjIpKSArDQogICBmYWNldF9ncmlkKHJvd3MgPSB2YXJzKHJpc2tfZGlzdHJpYnV0aW9uX3RyYW5zbCkgKSsNCiAgIHhsYWIoIlNhbXBsZSBTaXplIikrDQogICB5bGFiKCdEaWZmZXJlbmNlIHRvICJUcnVlIiBTY29yZScpKw0KICAgI3NjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKC0uMSwgLTAuNSwgMCwgLjA1LCAuMSwgLjE1LCAuMikpDQogICAjYW5ub3RhdGUoInRleHQiLCB4ID0gbGVuZ3RoKHNhbXBsZV9zZXF1ZW5jZSkvMiwgeSA9LjIgLCBjb2xvciA9IGNvbG9yc1sxXSwgbGFiZWwgPSB1bmlxdWUocmlza19kaXN0cmlidXRpb25fdHJhbnNsWzFdKSkNCiAgIGdlb21fdGV4dChhZXMoeCA9bGVuZ3RoKHNhbXBsZV9zZXF1ZW5jZSkvMiwgeSA9IHF1YW50aWxlKHltYXgsIHByb2JzID0uODUpKy4yNCwgbGFiZWwgPSByaXNrX2Rpc3RyaWJ1dGlvbl90cmFuc2wpLCBzaXplID0gNi41KQ0KYGBgDQoNCiMjIyBUYWJsZQ0KDQpgYGB7cn0NCmRmX0dyb3VwX0RpdmVyZ2VuY2VbLGNvbF90b190YWtlX2Zvcl90YWJsZV0gJT4lIA0KICAgbXV0YXRlX2F0KDM6NiwgLmZ1bnMgPSB+cm91bmQoLiwgZGlnaXRzID0gMykpJT4lDQogICBwYWdlZF90YWJsZShvcHRpb25zID0gbGlzdChyb3duYW1lcy5wcmludCA9IEYsIHJvd3MucHJpbnQgPSBsZW5ndGgoc2FtcGxlX3NlcXVlbmNlKSkpDQpgYGANCg0KIyMgUG9sYXJpemF0aW9uIEluZGV4IHsudGFic2V0fQ0KDQojIyMgUGxvdHMNCg0KYGBge3J9DQpkZl9Qb2xhcml6YXRpb25fSW5kZXggJT4lIA0KICAgbXV0YXRlKHltaW4gPSBgTWVhbiBEaWZmZXJlbmNlYC0gYFNEIERpZmZlcmVuY2VgLA0KICAgICAgICAgIHltYXggPSBgTWVhbiBEaWZmZXJlbmNlYCArIGBTRCBEaWZmZXJlbmNlYCkgJT4lIA0KICAgZ2dwbG90KGFlcyhmc2FtcGxlX3NpemUsIGBNZWFuIERpZmZlcmVuY2VgLCBncm91cCA9IHJpc2tfZGlzdHJpYnV0aW9uX3RyYW5zbCwgY29sID0gcmlza19kaXN0cmlidXRpb25fdHJhbnNsKSkrDQogICBnZW9tX2xpbmUobGluZXdpZHRoID0gMS4wNSkrDQogICBnZW9tX3BvaW50KHNpemUgPSAxLjgpKw0KICAgdGhlbWVfYncoKSsNCiAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xvcnMpKw0KICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgbGVnZW5kLmRpcmVjdGlvbiA9ICJob3Jpem9udGFsIiwNCiAgICAgICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICAjc3RyaXAucGxhY2VtZW50ID0gInRvcCIsDQogICAgICAgICBsZWdlbmQua2V5LnNpemUgPSB1bml0KDIuNCwgImxpbmVzIiksDQogICAgICAgICBsZWdlbmQua2V5ID0gZWxlbWVudF9yZWN0KGZpbGwgPSAidHJhbnNwYXJlbnQiKSwNCiAgICAgICAgIGxlZ2VuZC5ib3guYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0LjUpKSsNCiAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAgLCBjb2w9ImJsYWNrIiwgbGluZXR5cGU9ICJkYXNoZWQiLCBsaW5ld2lkdGggPSAxLjEpKw0KICAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IHltaW4sIHltYXggPSB5bWF4LCB3aWR0aCA9IC4yKSkgKw0KICAgZmFjZXRfZ3JpZChyb3dzID0gdmFycyhyaXNrX2Rpc3RyaWJ1dGlvbl90cmFuc2wpICkrDQogICB4bGFiKCJTYW1wbGUgU2l6ZSIpKw0KICAgeWxhYignRGlmZmVyZW5jZSB0byAiVHJ1ZSIgU2NvcmUnKSsNCiAgICNzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygtLjEsIC0wLjUsIDAsIC4wNSwgLjEsIC4xNSwgLjIpKQ0KICAgI2Fubm90YXRlKCJ0ZXh0IiwgeCA9IGxlbmd0aChzYW1wbGVfc2VxdWVuY2UpLzIsIHkgPS4yICwgY29sb3IgPSBjb2xvcnNbMV0sIGxhYmVsID0gdW5pcXVlKHJpc2tfZGlzdHJpYnV0aW9uX3RyYW5zbFsxXSkpDQogICBnZW9tX3RleHQoYWVzKHggPWxlbmd0aChzYW1wbGVfc2VxdWVuY2UpLzIsIHkgPSBxdWFudGlsZSh5bWF4LCBwcm9icyA9Ljg1KSsuMSwgbGFiZWwgPSByaXNrX2Rpc3RyaWJ1dGlvbl90cmFuc2wpLCBzaXplID0gNi41KSsNCiAgIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC0uMSwgLjIpKQ0KYGBgDQoNCiMjIyBUYWJsZQ0KDQpgYGB7cn0NCmRmX1BvbGFyaXphdGlvbl9JbmRleFssY29sX3RvX3Rha2VfZm9yX3RhYmxlXSAlPiUgDQogICBtdXRhdGVfYXQoMzo2LCAuZnVucyA9IH5yb3VuZCguLCBkaWdpdHMgPSAzKSklPiUNCiAgIHBhZ2VkX3RhYmxlKG9wdGlvbnMgPSBsaXN0KHJvd25hbWVzLnByaW50ID0gRiwgcm93cy5wcmludCA9IGxlbmd0aChzYW1wbGVfc2VxdWVuY2UpKSkNCmBgYA0KDQojIyBTaXplIFBhcml0eSB7LnRhYnNldH0NCg0KIyMjIFBsb3RzDQoNCmBgYHtyfQ0KZGZfU2l6ZV9QYXJpdHkgJT4lIA0KICAgbXV0YXRlKHltaW4gPSBgTWVhbiBEaWZmZXJlbmNlYC0gYFNEIERpZmZlcmVuY2VgLA0KICAgICAgICAgIHltYXggPSBgTWVhbiBEaWZmZXJlbmNlYCArIGBTRCBEaWZmZXJlbmNlYCkgJT4lIA0KICAgZ2dwbG90KGFlcyhmc2FtcGxlX3NpemUsIGBNZWFuIERpZmZlcmVuY2VgLCBncm91cCA9IHJpc2tfZGlzdHJpYnV0aW9uX3RyYW5zbCwgY29sID0gcmlza19kaXN0cmlidXRpb25fdHJhbnNsKSkrDQogICBnZW9tX2xpbmUobGluZXdpZHRoID0gMS4wNSkrDQogICBnZW9tX3BvaW50KHNpemUgPSAxLjgpKw0KICAgdGhlbWVfYncoKSsNCiAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xvcnMpKw0KICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgbGVnZW5kLmRpcmVjdGlvbiA9ICJob3Jpem9udGFsIiwNCiAgICAgICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICAjc3RyaXAucGxhY2VtZW50ID0gInRvcCIsDQogICAgICAgICBsZWdlbmQua2V5LnNpemUgPSB1bml0KDIuNCwgImxpbmVzIiksDQogICAgICAgICBsZWdlbmQua2V5ID0gZWxlbWVudF9yZWN0KGZpbGwgPSAidHJhbnNwYXJlbnQiKSwNCiAgICAgICAgIGxlZ2VuZC5ib3guYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0LjUpKSsNCiAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAgLCBjb2w9ImJsYWNrIiwgbGluZXR5cGU9ICJkYXNoZWQiLCBsaW5ld2lkdGggPSAxLjEpKw0KICAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IHltaW4sIHltYXggPSB5bWF4LCB3aWR0aCA9IC4yKSkgKw0KICAgZmFjZXRfZ3JpZChyb3dzID0gdmFycyhyaXNrX2Rpc3RyaWJ1dGlvbl90cmFuc2wpICkrDQogICB4bGFiKCJTYW1wbGUgU2l6ZSIpKw0KICAgeWxhYignRGlmZmVyZW5jZSB0byAiVHJ1ZSIgU2NvcmUnKSsNCiAgICNzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygtLjEsIC0wLjUsIDAsIC4wNSwgLjEsIC4xNSwgLjIpKQ0KICAgI2Fubm90YXRlKCJ0ZXh0IiwgeCA9IGxlbmd0aChzYW1wbGVfc2VxdWVuY2UpLzIsIHkgPS4yICwgY29sb3IgPSBjb2xvcnNbMV0sIGxhYmVsID0gdW5pcXVlKHJpc2tfZGlzdHJpYnV0aW9uX3RyYW5zbFsxXSkpDQogICBnZW9tX3RleHQoYWVzKHggPWxlbmd0aChzYW1wbGVfc2VxdWVuY2UpLzIsIHkgPSBxdWFudGlsZSh5bWF4LCBwcm9icyA9LjEpLS4xNSwgbGFiZWwgPSByaXNrX2Rpc3RyaWJ1dGlvbl90cmFuc2wpLCBzaXplID0gNi41KSsNCiAgIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC0uMiwgLjEpKQ0KYGBgDQoNCiMjIyBUYWJsZQ0KDQpgYGB7cn0NCmRmX1NpemVfUGFyaXR5Wyxjb2xfdG9fdGFrZV9mb3JfdGFibGVdICU+JSANCiAgIG11dGF0ZV9hdCgzOjYsIC5mdW5zID0gfnJvdW5kKC4sIGRpZ2l0cyA9IDMpKSU+JQ0KICAgcGFnZWRfdGFibGUob3B0aW9ucyA9IGxpc3Qocm93bmFtZXMucHJpbnQgPSBGLCByb3dzLnByaW50ID0gbGVuZ3RoKHNhbXBsZV9zZXF1ZW5jZSkpKQ0KYGBgDQoNCiMgRGlzY3Vzc2lvbg0KDQpJdCBzZWVtcyBsaWtlIHRoYXQgdGhlcmUgaXMgYSBjZXJ0YWluIHBhdHRlcm4gaW4gdGhlIHBsb3RzOiAgDQoNCi0gQXMgZXhwZWN0ZWQsIHRoZSBoaWdoZXIgdGhlIHNhbXBsZSBzaXplIGluY3JlYXNlcywgdGhlIG1vcmUgdGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gdGhlIHNhbXBsZSBhbmQgdGhlIHBvcHVsYXRpb24gY29udmVyZ2VzIHRvIDAsIG1lYW5pbmcgdGhhdCB3ZSBnZXQgYSBtb3JlIGFjY3VyYXRlIGVzdGltYXRlLiAgDQoNCi0gTGlrZXdpc2UsIHRoZSBlcnJvciBiYXJzIGRlY2xpbmUgd2l0aCBpbmNyZWFzaW5nIHNhbXBsZSBzaXplLiAgDQoNCi0gVGhlIGRpZmZlcmVudCBwb2xhcml6YXRpb24gbWVhc3VyZXMgaGF2ZSBkaWZmZXJlbnQgc3RyZW5ndGhzIGFuZCB3ZWFrbmVzc2VzOiAgDQogICAtIEFsbW9zdCBhbGwgbWVhc3VyZXMgd2VyZSBhYmxlIHRvIGFjY3VyYXRlbHkgZXN0aW1hdGUgdGhlIHRydWUgc2NvcmUgb24gdGhlIFsqKm5vcm1hbCBkaXN0cmlidXRpb24qKl17c3R5bGU9ImNvbG9yOiBgciBjb2xvcnNbMV1gOyJ9LCBleGNlcHQgZm9yICpzaXplIHBhcml0eSouIENvbnNpZGVyaW5nIHRoYXQgdGhpcyBtZWFzdXJlIHVzZXMgZ3JvdXAgc2l6ZXMgb2YgbG93IHZzIGhpZ2ggdmFsdWVzIHNwbGl0IGJ5IHRoZSBtaWRwb2ludCBvZiBhIHNjYWxlLCBzZXR0aW5nIHRoZSBtZWFuIG9mIHRoZSBub3JtYWwgZGlzdHJpYnV0aW9uIHRvIHRoZSBtaWRwb2ludCB3YXMgYSBkZXRyaW1lbnQgdG8gdGhpcyBtZWFzdXJlLiAgDQogICAtICpTaXplIHBhcml0eSogc3RydWdnbGVzIHdpdGggdGhlIFsqKnNrZXdlZCBiZXRhIGRpc3RyaWJ1dGlvbioqXXtzdHlsZT0iY29sb3I6IGByIGNvbG9yc1syXWA7In0gYXMgd2VsbC4gSXQgc2VlbXMgbGlrZSBwYXJ0aXRpb25pbmcgdGhlIHJhdGluZ3MgaW50byBoYWx2ZXMgaGFzIGl0cyBkaXNhZHZhbnRhZ2VzIHdoZW4gc2FtcGxpbmcgZnJvbSBzb21ldGhpbmcgdGhhdCBpcyBza2V3ZWQgbGlrZSB0aGF0LiAgDQogICAtIExvb2tpbmcgYXQgdGhlIFsqKm1peGVkIGRpc3RyaWJ1dGlvbioqXXtzdHlsZT0iY29sb3I6IGByIGNvbG9yc1szXWA7In0sIHRoZSAqYmltb2RhbGl0eSBjb2VmZmljaWVudCwgY292ZXJhZ2UgYW5kIGdyb3VwIGRpdmVyZ2VuY2UqIGhhZCByYXRoZXIgYmlnIGVycm9yIGJhcnMuICANCiAgIC0gTG9va2luZyBhdCB0aGUgWyoqc3ltbWV0cmljIGJldGEgZGlzdHJpYnV0aW9uKipde3N0eWxlPSJjb2xvcjogYHIgY29sb3JzWzRdYDsifSwgdGhlICpwb2xhcml6YXRpb24sIGRpc3BlcnNpb24sIHBvbGFyaXphdGlvbiBpbmRleCBhbmQgc2l6ZSBwYXJpdHkqIHdlcmUgb2ZmIGZvciBzbWFsbGVyIGFuZCBldmVuIG1lZGl1bSBzYW1wbGUgc2l6ZXMuICANCg0KDQotIE92ZXJhbGwsIHRoZSBtaXhlZCBhbmQgc3ltbWV0cmljIGJldGEgZGlzdHJpYnV0aW9ucyB3ZXJlIHRoZSBtb3N0IGRpZmZpY3VsdCBmb3Igb3VyIGNhbmRpZGF0ZSBtZWFzdXJlcyB0byBhcHByb3hpbWF0ZSB0byB0aGUgInRydWUgc2NvcmUiLiBTYWRseSwgdGhlc2UgYXJlIHRoZSBkaXN0cmlidXRpb25zIHdoaWNoIG1vc3Qgd291bGQgY2FsbCBwb2xhcml6ZWQsIGFuZCB3aGljaCB0aGUgc3R1ZHkgd2FudHMgdG8gdW5jb3Zlci4gVGhlcmVmb3JlLCBhIGdyZWF0ZXIgbnVtYmVyIG9mIHJhdGluZ3MgaXMgYWR2aXNlZCB0byByZWxpYWJsZSBlc3RpbWF0ZSB0aGUgZXh0ZW5kIG9mIHBvbGFyaXphdGlvbiBpbiB0aGUgcG9wdWxhdGlvbi4gIA0KDQpCZWluZyBhYmxlIHRvIGVzdGltYXRlIHRoZSBwb3B1bGF0aW9uIHdpdGggb3VyIG1lYXN1cmVzIGlzIGdvb2QgYW5kIGFsbCwgYnV0IG9uZSBpbXBvcnRhbnQgYXNwZWN0IG9mIGNob29zaW5nIGEgbWVhc3VyZSBhbHNvIGluY2x1ZGVzIGhvdyBtdWNoIHZhcmlhYmlsaXR5IGl0IGhhcyBpbiBkaWZmZXJlbnQgcmlza3MuIEZvciBleGFtcGxlLCBpZiBhIG1lYXN1cmUgaW5kaWNhdGVzIGEgcG9sYXJpemF0aW9uIHZhbHVlIG9mIC41IGZvciBkaWZmZXJlbnQgcmlza3MgKGhlbmNlIGxvdyB2YXJpYWJpbGl0eSksIGlzIG91ciBjaG9zZW4gbWVhc3VyZSBnb29kIGJlY2F1c2Ugd2UgY2FuIGRldGVjdCB0aGUgdHJ1ZSBzY29yZSBpbiB0aGUgcG9wdWxhdGlvbiB3aXRoIGV2ZW4gc21hbGwgc2FtcGxlcyAoYXMgdGhlIGNvbXBhcmlzb24gb2Ygc2FtcGxlIGFuZCB0cnVlIHNjb3JlIHdhcyBkZXJpdmVkIGZyb20gdGhlIHNhbWUgbWV0aG9kKT8gT3IgaXMgaXQgb3V0cmlnaHQgYmFkIGJlY2F1c2UgaXQgaXMgYWdub3N0aWMgdG93YXJkcyBtb3N0IHJpc2tzIGFuZCB0aHVzIGRvZXMgbm90IGRldGVjdCB0aGUgZGlmZmVyZW50IG51YW5jZXMgb2YgYSByaXNrIGRpc3RyaWJ1dGlvbj8gVGhlIGJlc3QgZXhhbXBsZSBoZXJlIHdvdWxkIGJlIHRvIGxvb2sgYXQgdGhlIG1lYXN1cmUgKmNvdmVyYWdlKiBpbiBvdXIgdHJ1ZSBzY29yZSBkaXN0cmlidXRpb25zLiBJdCBzY29yZWQgdGhlIGJlc3Qgb3V0IG9mIGFsbCB0aGUgbWVhc3VyZXMgd2hlbiBvbmx5IGxvb2tpbmcgYXQgdGhlIGRpZmZlcmVuY2UgdG8gdGhlICJ0cnVlIHNjb3JlIiwgYnV0IG9uIGEgY2xvc2VyIGxvb2ssIGRvZXMgbm90IGRpZmZlcmVudGlhdGUgYmV0d2VlbiB0aGUgWyoqc3ltbWV0cmljIGJldGEqKl17c3R5bGU9ImNvbG9yOiBgciBjb2xvcnNbNF1gOyJ9IGFuZCB0aGUgWyoqbm9ybWFsIGRpc3RyaWJ1dGlvbnMqKl17c3R5bGU9ImNvbG9yOiBgciBjb2xvcnNbMV1gOyJ9LCB3aGljaCBtb3N0IHdvdWxkIHRoaW5rIGFyZSB0b3RhbGx5IGRpZmZlcmVudC4gVGh1cywgY292ZXJhZ2UgbWF5IG5vdCBiZSBhIGdvb2QgbWVhc3VyZSBmb3IgcG9sYXJpemF0aW9uIChvciBhdCBsZWFzdCBub3QgdGhlIHdheSBJIHNlZSBpdCkuICANCg0KVGFraW5nIHNldmVyYWwgbWVhc3VyZXMgYXMgYSBvcGVyYXRpb25hbGl6YXRpb24gb2YgcG9sYXJpemF0aW9uIGlzIHByb2JhYmx5IGEgYmV0dGVyIGFwcHJvYWNoIHRoYW4gYmFua2luZyBvdXIgc3R1ZHkgd2l0aCBqdXN0IG9uZS4gQXMgc3VjaCwgdGhlIGF1dGhvciBub21pbmF0ZXMgdGhlICpiaW1vZGFsaXR5IGNvZWZmaWNpZW50LCBwb2xhcml6YXRpb24gYW5kIGdyb3VwIGRpdmVyZ2VuY2UqIGFzIHRoZSBnbyB0byBtZWFzdXJlcyBmb3IgdGhlIHVwY29taW5nIHN0dWR5LiBUaGVzZSBtZWFzdXJlcyB3ZXJlIHRha2VuIGJlY2F1c2Ugb2YgdGhlIGZvbGxvd2luZyByZWFzb25zOiAgDQoNCi0gVGhlc2UgbWVhc3VyZXMgY29tcGxlbWVudCBlYWNoIG90aGVyIGFuZCBjb21wZW5zYXRlIGZvciBlYWNoIG90aGVyJ3Mgd2Vha25lc3NlczogIA0KICAgLSBUaGUgKmJpbW9kYWxpdHkgY29lZmZpY2llbnQqIHVzZXMgc2tld25lc3MgYW5kIGt1cnRvc2lzLCBoZW5jZSB1c2VzIHNvbWUgc29ydCBvZiAqKmFzeW1tZXRyeSBhbmQgImhlYXZpbmVzcyIqKiBkZXRlY3Rpb24gaW4gYSBkaXN0cmlidXRpb24uIEhvd2V2ZXIsIGJpYXNlcyBpbiB0aGUgZGlzdHJpYnV0aW9uIGNhbiBsZWFkIHRvIGJpYXNlcyBpbiB0aGUgYWZvcmVtZW50aW9uZWQgbWV0cmljcyBhcyB3ZWxsLCB3aGljaCBzY3Jld3MgdGhlIHZhbGlkaXR5IG9mIHRoaXMgbWVhc3VyZS4gVGh1cyBpdCBpcyBub3QgcGVyZmVjdGx5IHNlbnNpdGl2ZSBhbmQgc3BlY2lmaWMgdG8gYXNzZXNzIGJpbW9kYWxpdHkuICANCiAgIC0gVGhlIG1lYXN1cmUgb2YgKnBvbGFyaXphdGlvbiogYWN0cyBhcyBhIHNvcnQgb2YgKiphZ3JlZW1lbnQgbWVhc3VyZSoqIChzdW1tZWQgd2VpZ2h0cyBvZiBvcmRlcmVkIGJpbnMpLiBJdHMgc3RyZW5ndGhzIGlzIGl0cyBiaWdnZXN0IGZsYXcsIGFzIGl0IGlnbm9yZXMgbWlub3JpdHkgZ3JvdXBzIGV2ZW4gdGhvdWdoIHRoZXkgbWF5IGFsc28gY29udHJpYnV0ZSB0byBwb2xhcml6YXRpb24gKGxpa2Ugb3VyIFsqKm1peGVkIGRpc3RyaWJ1dGlvbioqXXtzdHlsZT0iY29sb3I6IGByIGNvbG9yc1szXWA7In0pLiAgDQogICAtICpHcm91cCBkaXZlcmdlbmNlKiBpcyBhIG1lYXN1cmUgd2hpY2ggdGFrZXMgaW50byBhY2NvdW50IGhvdyBiaWcgdGhlIChtZWFuKSAqKmRpc3RhbmNlIGJldHdlZW4gdHdvIHNpZGVzKiogb2YgYSBtaWRwb2ludCBpcy4gVGhlIHByb2JsZW0gb2YgdGhpcyBtZXRyaWMgaXMgdGhhdCBpdCBpcyBhZ25vc3RpYyB0byB0aGUgZXhhY3QgZGlzdHJpYnV0aW9uIGFuZCBncm91cCBzaXplcy4gIA0KLSBBcmUgYWJsZSB0byBkaWZmZXJlbnRpYXRlIGJldHdlZW4gZGlmZmVyZW50IHR5cGVzIG9mIGRpc3RyaWJ1dGlvbnMuICANCi0gV2hpbGUgYWxzbyBiZWluZyBzb21ld2hhdCB1c2FibGUgYXMgYSBzdGFuZGFsb25lIG1lYXN1cmUuICANCg0KQWRkaXRpb25hbGx5LCB0aGUgKmJpbW9kYWxpdHkgY29lZmZpY2llbnQqIGhhcyBhIG1hdGhlbWF0aWNhbGx5IGRlcml2ZWQgdGhyZXNob2xkIG9mIGFyb3VuZCAkMC5cb3ZlcmxpbmV7NX0kLiBEaXN0cmlidXRpb25zIHVuZGVyIHRoaXMgdGhyZXNob2xkIGNhbiBiZSB0YWtlbiBhcyBhbiBpbmRpY2F0aW9uIHRvd2FyZHMgdW5pbW9kYWxpdHksIHdoZXJlYXMgdmFsdWVzIGFib3ZlIHRoaXMgdGhyZXNob2xkIGNhbiBiZSBzZWVuIGFzIGFuICoqaW5kaWNhdG9yIHRvd2FyZHMgYmltb2RhbGl0eSoqLCBzb21ldGhpbmcgYWtpbiB0byBwb2xhcml6YXRpb24uIFRob3VnaCwgYXMgYWxyZWFkeSBtZW50aW9uZWQsIGl0IGFsc28gaGFzIHNvbWUgW2xpbWl0YXRpb25zXShodHRwczovL3d3dy5mcm9udGllcnNpbi5vcmcvam91cm5hbHMvcHN5Y2hvbG9neS9hcnRpY2xlcy8xMC4zMzg5L2Zwc3lnLjIwMTMuMDA3MDAvZnVsbCkuLi4gIA0KDQpXaXRoIHRoZXNlIDMgbWVhc3VyZXMsIHRoZSBhdXRob3IgYXJndWVzIGZvciBhdCBsZWFzdCAxMDAgcmF0aW5ncyBwZXIgcmlzay4uLi4gVGhvdWdoIGl0IGRvZXMgbm90IHNlZW0gbGlrZSB0aGlzIHdvcmsgd2FzIG9mIGFueSBoZWxwIGF0IGFsbCBjb25jZXJuaW5nIFtwb3dlciBhbmFseXNpc10oUmlzay1Qb2xhcml6YXRpb24tUG93ZXItQW5hbHlzaXMuaHRtbCkuLi4gIA0KDQpPbiBhbm90aGVyIG5vdGUsIGRldGVjdGluZyBwb2xhcml6YXRpb24gYWxzbyBkZXBlbmRzIChhcyBtZW50aW9uZWQgbWFueSB0aW1lcyBiZWZvcmUpIG9uIHRoZSB1bmRlcmx5aW5nIGRpc3RyaWJ1dGlvbi4gVGhlIG1lYXN1cmVzIGFyZSBvbmx5IHRvb2xzIHRvIGRldGVjdCB3aGV0aGVyIHNvbWV0aGluZyBpcyBwb2xhcml6ZWQsIGJ1dCB3aGVuIHNvbWV0aGluZyBpcyBub3QgcG9sYXJpemVkLCB0aGVyZSBjYW4gYmUgZGlmZmVyZW50IHJlYXNvbnM6ICANCiAgDQotIFRoZSBzYW1wbGUgc2l6ZSB3YXMgdG9vIHNtYWxsIHRvIHVuY292ZXIgcG9sYXJpemF0aW9uLiAgDQotIFRoZSBtZWFzdXJlIGNhbiBub3QgZGV0ZWN0IHBvbGFyaXphdGlvbi4gIA0KLSBUaGUgcmlzayBpdHNlbGYgaXMgcG9sYXJpemVkLCBidXQgb25seSBpbiBhICh1bmtub3duKSBzdWJncm91cC4gIA0KLSBUaGUgcmlzayBpdHNlbGYgaXMgbm90IHBvbGFyaXplZC4gIA0KDQpJbiBhY2NvcmRhbmNlIHdpdGggdGhlIHRoaXJkIHBvaW50IHJhaXNlZCBhYm92ZSwgdGhlIGRlY2lzaW9uIGhvdyB0byBzYW1wbGUgZnJvbSB0aGUgcG9wdWxhdGlvbiBmdW5jdGlvbnMgYXMgYSBzb3J0IG9mIHdpbmRvdyBwbGFjZW1lbnQuIE9uZSBjYW4gem9vbSBpbiBhbmQgb3V0IChlLmcuIGluY3JlYXNlIHNhbXBsZSBzaXplIGFuZCB0aGVyZWZvcmUgcG93ZXIpLCBidXQgd2hlbiB0aGUgd2luZG93IHdhcyBzZXQgaW4gYSBzdWIgb3B0aW1hbCB3YXksIGl0IGdldHMgZXZlbiBtb3JlIGRpZmZpY3VsdCB0byBzYW1wbGUgdGhlIHJpZ2h0IHBlb3BsZSB3aXRoIGRpZmZlcmluZyBvcGluaW9uLiAgDQoNCiMjIExpbWl0YXRpb25zDQoNCi0gICBTY2FsZSBsaW1pdHMgaW4gc2FtcGxlcyBoYWQgdG8gYmUgcm91bmRlZCBzbyBzb21lIG1lYXN1cmVzIGNhbiBiZSBjYWxjdWxhdGVkLCB3aGljaCBtYXkgbm90IGJlIGFwcHJvcHJpYXRlIChlLmcuIDAuMDczNjU3IHRvIDAuMDcpLiBUaG91Z2ggb3VyIHJhdGluZ3MgYXJlIGRpc2NyZXRlIGFzIHdlbGwsIHNvIHRoaXMgbWF5IGV2ZW4gYmUgbW9yZSBlY29sb2dpY2FseSB2YWxpZC5cDQotICAgV2hpbGUgdGhlIHZhbHVlcyBvZiB0aGUgc2FtcGxlcyB3ZXJlIHJvdW5kZWQsIHRoZSB2YWx1ZXMgaW4gdGhlIHBvcHVsYXRpb24gd2VyZSBub3QuIFRoaXMgc2hvdWxkIG5vdCBtYWtlIGEgZGlmZmVyZW5jZSBmcm9tIGEgKiptYXRoZW1hdGljYWwqKiBwZXJzcGVjdGl2ZSBmb3IgdGhlIG1lYXN1cmVzIChtb3JlIGdyYW51bGFyLyBmaW5lciBkZXRhaWwpLiBJdCBtYXksIGhvd2V2ZXIsIGhpbmRlciB0aGUgY29tcGFyaXNvbiB0byBvdXIgY2FsY3VsYXRlZCBtZWFzdXJlcyBpbiB0aGUgc2ltdWxhdGVkIHNhbXBsZXMuXA0KLSAgIE9ubHkgYHIgbnJvdyhkZilgIHJpc2sgZGlzdHJpYnV0aW9ucyB3ZXJlIHNpbXVsYXRlZC5cDQotICAgU3ByZWFkIGFuZCBHcm91cCBEaXN0aW5jdG5lc3Mgd2VyZSBsZWZ0IG91dCBpbiB0aGlzIHNpbXVsYXRpb24uICANCi0gVGhlIHNpbXVsYXRpb24gdXNlZCBhIHNjYWxlIG9mIDAgdG8gMSB3aXRoIGluY3JlbWVudHMgb2YgMC4wMSwgd2hpY2ggYWxzbyB0cmFuc2xhdGVzIHRvIDEwMSBkaWZmZXJlbnQgc2NhbGVzLiBXaGV0aGVyIHRoZSByZXN1bHRzIHN0aWxsIGhvbGRzIGZvciBsZXNzIGdyYW51bGFyIHNjYWxlcyBpcyB1cCBmb3IgZGViYXRlLiAgDQotIEFzIG1lbnRpb25lZCBpbiB0aGUgbWV0aG9kIHNlY3Rpb24sIHRoZSBNb250ZSBDYXJsbyBhcHByb2FjaCBsaXZlcyBhbmQgZmFsbHMgd2l0aCB0aGUgdW5kZXJseWluZyBkaXN0cmlidXRpb24sIHdoaWNoIHdlIGFzc3VtZSBpcyBhbHNvIHByZXNlbnQgaW4gdGhlIHBvcHVsYXRpb24uIEJ1dCBhcyBhbGwgdGhpbmdzIGluIGxpZmUsIHRoZSBkaXN0cmlidXRpb25zIG1heSBsb29rIGNvbXBsZXRlbHkgZGlmZmVyZW50LiBJcnJlZ3VsYXJpdGllcyBhbmQgZGlzY29udGludWl0aWVzIG1heSBldmVuIGJlIHRoZSBub3JtIHRoYW4gdGhlIGV4Y2VwdGlvbi4gIA0KLSBJbnRlcnByZXRpbmcgc3VjaCBhIHdvcmsgaXMgYSBmaXJzdCBmb3IgbWUsIHBsZWFzZSBiZSB3YXJ5IG9mIG15IHBvc3NpYmx5IGJpYXNlZCB2aWV3IGluIHRoaXMuIFRoaXMgaXMgYWxzbyByZWZsZWN0ZWQgaW4gdGhlIGxvdyBjb3VudCBpbiB0aGUgcmVmZXJlbmNlcywgd2hlcmUgSSBhcmd1ZSBtb3N0bHkgd2l0aCB0aGUgZGF0YSBhbmQgaW50dWl0aW9uLCB3aGljaCBpcyBzdWJqZWN0aXZlLiBQbGVhc2UgZm9ybXVsYXRlIHlvdXIgb3duIG9waW5pb24gb24gdGhpcyBtYXR0ZXIhICANCg0KDQojIyBDb25jbHVzaW9ucw0KDQotIE5vICJvbmUgc2l6ZSBmaXRzIGFsbCIgbWVhc3VyZSwgYnV0IHRocmVlIGNhbmRpZGF0ZSBtZWFzdXJlcyBvZiAqYmltb2RhbGl0eSBjb2VmZmljaWVudCwgcG9sYXJpemF0aW9uIGFuZCBncm91cCBkaXZlcmdlbmNlKiB3ZXJlIG5vbWluYXRlZC4gICAgDQotIE5vIGNsZWFyIGN1dCBhbnN3ZXIgZm9yIGhvdyBtYW55IHBhcnRpY2lwYW50cyBzaG91bGQgYmUgc2FtcGxlZC4gIA0KLSBXaGlsZSBzYW1wbGUgc2l6ZSBwbGF5cyBhIGtleSByb2xlIGluIGRldGVjdGluZyBwb2xhcml6YXRpb24sIHNhbXBsaW5nIGZyb20gYSBwb3B1bGF0aW9uIHdoZXJlIHdlIGFzc3VtZSBwb2xhcml6YXRpb24gdG8gYmUgbW9yZSBwcmVzZW50IGlzIGFuIGV2ZW4gbW9yZSBpbXBvcnRhbnQgZmFjdG9yLCBhcyBpdCB0ZWNobmljYWxseSBzZXRzIHRoZSAiYmFzZSByYXRlIiBvZiBkaWZmZXJpbmcgb3BpbmlvbnMuICANCg0KDQojIENyZWRpdHMNCg0KIyMgQWNrbm93bGVkZ2VtZW50cyBhbmQgb3RoZXJzDQoNClRoaXMgd29yayB3YXMgZG9uZSB3aXRoaW4gMiB3ZWVrcyBpbiBjb250ZXh0IG9mIHRoZSBtYXN0ZXIgcHJvamVjdCBpbiBteSBNU2MuIGluIHBzeWNob2xvZ3kgYXQgdGhlIHVuaXZlcnNpdHkgb2YgQmFzZWwgd2l0aGluIHRoZSBbQ0RTXShodHRwczovL3BzeWNob2xvZ2llLnVuaWJhcy5jaC9kZS9mYWt1bHRhZXQvYWJ0ZWlsdW5nZW4vY29nbml0aXZlLWFuZC1kZWNpc2lvbi1zY2llbmNlcy0zMDUvKSBkZXBhcnRtZW50LiAgDQoNCkkgdGhhbmsgUHJvZi4gRHIuIFJ1aSBNYXRhIGZvciB0aGUgc3VwZXJ2aXNpb24gYW5kIGNvbnRpbnVlZCBndWlkYW5jZSBpbiB0aGUgbWFzdGVyIHByb2plY3QuICANCg0KSW4gYWRkaXRpb24sIEkgd291bGQgbGlrZSB0byBleHRlbmQgbXkgYXBwcmVjaWF0aW9uIHRvIHRoZSBtZW1iZXJzIGluIHRoZSByaXNrIHBvbGFyaXphdGlvbiBncm91cCwgbmFtZWx5OiAgDQogIA0KICANCiAtIEdvZXR6LCBGYWJpZW5uZSAgDQogLSBMZXV0d3lsZXIsIFZhbmVzc2EgIA0KIC0gTGljaHRuZXIsIEx1a2FzICANCiAtIFJvc2EsIEZsYXZpYSAgDQogLSBXaWxsaSwgTm9haCAgDQoNClRoZSBjb2RlIHVzZWQgZm9yIHRoaXMgd29yayBjYW4gYmUgZG93bmxvYWRlZCBpbiB0aGUgdXBwZXIgcmlnaHQgY29ybmVyIGluIHRoZSBiZWdpbm5pbmcgb2YgdGhpcyBIVE1MIGZpbGUuICANCkluIGNhc2UgeW91IGhhdmUgb3RoZXIgcXVlc3Rpb25zIG9yIHJlbWFya3MsIGZlZWwgZnJlZSB0byBjb250YWN0IG1lIHVuZGVyOiBbYW5keS5jYW9AdW5pYmFzLmNoXShtYWlsdG86YW5keS5jYW9AdW5pYmFzLmNoKSAgDQp+flBsZWFzZSByZWZyYWluIGZyb20gY3JpdGljaXppbmcgdGhpcyB3b3JrIGZvciBub3QgY29uZm9ybWluZyB0byBBUEEgc3R5bGUgZ3VpZGVsaW5lcywgcmVwb3J0aW5nIGluIGEgbm9uLXNjaWVudGlmaWMgbWFubmVyLCBhbmQgZm9ybWF0dGluZyBjaG9pY2VzLn5+DQoNCkxhc3RseSwgSSB3b3VsZCBsaWtlIHRvIHRoYW5rIHRob3NlIHdobyByZWFkIHRoaXMgd2hvbGUgd29yayBmcm9tIHRvcCB0byBib3R0b20uIFNpbXVsdGFuZW91c2x5IHRob3VnaCwgSSB3b3VsZCBsaWtlIHRvIGFwb2xvZ2l6ZSBmb3IgbXkgfn53YWxsIG9mIHRleHR+fiBvZGQgY2hvaWNlIG9mIHdvcmRzIGhlcmUgYW5kIHRoZXJlLg0KDQojIyBSIFBhY2thZ2VzIHVzZWQNCg0KLSBhZ3JtdCAoUnVlZGluIEQgKDIwMjMpLiBfYWdybXQ6IENhbGN1bGF0ZSBDb25jZW50cmF0aW9uIGFuZCBEaXNwZXJzaW9uIGluIE9yZGVyZWQgUmF0aW5nIFNjYWxlc18uIFIgcGFja2FnZSB2ZXJzaW9uIDEuNDIuMTIsDQo8aHR0cHM6Ly9DUkFOLlItcHJvamVjdC5vcmcvcGFja2FnZT1hZ3JtdD4uKSAgDQoNCi0gZG9QYXJhbGxlbCAoQ29ycG9yYXRpb24gTSwgV2VzdG9uIFMgKDIwMjIpLiBfZG9QYXJhbGxlbDogRm9yZWFjaCBQYXJhbGxlbCBBZGFwdG9yIGZvciB0aGUgJ3BhcmFsbGVsJyBQYWNrYWdlXy4gUiBwYWNrYWdlIHZlcnNpb24gMS4wLjE3LA0KPGh0dHBzOi8vQ1JBTi5SLXByb2plY3Qub3JnL3BhY2thZ2U9ZG9QYXJhbGxlbD4uKSAgDQoNCi0gZm9yZWFjaCAoTWljcm9zb2Z0LCBXZXN0b24gUyAoMjAyMikuIF9mb3JlYWNoOiBQcm92aWRlcyBGb3JlYWNoIExvb3BpbmcgQ29uc3RydWN0Xy4gUiBwYWNrYWdlIHZlcnNpb24gMS41LjIsIDxodHRwczovL0NSQU4uUi1wcm9qZWN0Lm9yZy9wYWNrYWdlPWZvcmVhY2g+LikgIA0KDQotIGtuaXRyIChYaWUgWSAoMjAyMykuIF9rbml0cjogQSBHZW5lcmFsLVB1cnBvc2UgUGFja2FnZSBmb3IgRHluYW1pYyBSZXBvcnQgR2VuZXJhdGlvbiBpbiBSXy4gUiBwYWNrYWdlIHZlcnNpb24gMS40NSwgPGh0dHBzOi8veWlodWkub3JnL2tuaXRyLz4uKSAgDQoNCi0gcHN5Y2ggKFdpbGxpYW0gUmV2ZWxsZSAoMjAyMykuIF9wc3ljaDogUHJvY2VkdXJlcyBmb3IgUHN5Y2hvbG9naWNhbCwgUHN5Y2hvbWV0cmljLCBhbmQgUGVyc29uYWxpdHkgUmVzZWFyY2hfLiBOb3J0aHdlc3Rlcm4gVW5pdmVyc2l0eSwgRXZhbnN0b24sIElsbGlub2lzLiBSDQpwYWNrYWdlIHZlcnNpb24gMi4zLjksIDxodHRwczovL0NSQU4uUi1wcm9qZWN0Lm9yZy9wYWNrYWdlPXBzeWNoPi4pICANCg0KLSBSQ29sb3JCcmV3ZXIgKE5ldXdpcnRoIEUgKDIwMjIpLiBfUkNvbG9yQnJld2VyOiBDb2xvckJyZXdlciBQYWxldHRlc18uIFIgcGFja2FnZSB2ZXJzaW9uIDEuMS0zLCA8aHR0cHM6Ly9DUkFOLlItcHJvamVjdC5vcmcvcGFja2FnZT1SQ29sb3JCcmV3ZXI+LikgIA0KDQotIHJtYXJrZG93biAoQWxsYWlyZSBKLCBYaWUgWSwgRGVydmlldXggQywgTWNQaGVyc29uIEosIEx1cmFzY2hpIEosIFVzaGV5IEssIEF0a2lucyBBLCBXaWNraGFtIEgsIENoZW5nIEosIENoYW5nIFcsIElhbm5vbmUgUiAoMjAyMykuIF9ybWFya2Rvd246IER5bmFtaWMNCkRvY3VtZW50cyBmb3IgUl8uIFIgcGFja2FnZSB2ZXJzaW9uIDIuMjUsIDxodHRwczovL2dpdGh1Yi5jb20vcnN0dWRpby9ybWFya2Rvd24+LikgIA0KDQotIHRpZHl2ZXJzZSAoV2lja2hhbSBILCBBdmVyaWNrIE0sIEJyeWFuIEosIENoYW5nIFcsIE1jR293YW4gTEQsIEZyYW7Dp29pcyBSLCBHcm9sZW11bmQgRywgSGF5ZXMgQSwgSGVucnkgTCwgSGVzdGVyIEosIEt1aG4gTSwgUGVkZXJzZW4gVEwsIE1pbGxlciBFLCBCYWNoZSBTTSwNCk3DvGxsZXIgSywgT29tcyBKLCBSb2JpbnNvbiBELCBTZWlkZWwgRFAsIFNwaW51IFYsIFRha2FoYXNoaSBLLCBWYXVnaGFuIEQsIFdpbGtlIEMsIFdvbyBLLCBZdXRhbmkgSCAoMjAxOSkuIOKAnFdlbGNvbWUgdG8gdGhlIHRpZHl2ZXJzZS7igJ0gX0pvdXJuYWwgb2YNCk9wZW4gU291cmNlIFNvZnR3YXJlXywgKjQqKDQzKSwgMTY4Ni4gZG9pOjEwLjIxMTA1L2pvc3MuMDE2ODYgPGh0dHBzOi8vZG9pLm9yZy8xMC4yMTEwNS9qb3NzLjAxNjg2Pi4pICANCg0KLSB2aXNkYXQgKFRpZXJuZXkgTiAoMjAxNykuIOKAnHZpc2RhdDogVmlzdWFsaXNpbmcgV2hvbGUgRGF0YSBGcmFtZXMu4oCdIF9KT1NTXywgKjIqKDE2KSwgMzU1LiBkb2k6MTAuMjExMDUvam9zcy4wMDM1NSA8aHR0cHM6Ly9kb2kub3JnLzEwLjIxMTA1L2pvc3MuMDAzNTU+LA0KPGh0dHA6Ly9keC5kb2kub3JnLzEwLjIxMTA1L2pvc3MuMDAzNTU+LikgIA0KICANCg0KDQojIyBVc2Ugb2YgQUkNCg0KQ2hhdEdQVCAzLjUgKE9wZW5BSS4gMjAyMywgaHR0cHM6Ly9jaGF0Lm9wZW5haS5jb20vY2hhdCk6ICANCg0KLSBHaXZpbmcgdGhlIGV4b3NrZWxldG9uIGZvciBwYXJhbGxlbCBjb21wdXRhdGlvbiB1c2luZyBtdWx0aXBsZSBjb3JlcyBhbmQgZm9yZWFjaCBwYWNrYWdlcy4gIA0KLSBQb2ludGluZyB0aGUgYXV0aG9yIHRvd2FyZHMgdGhlICJjdXQiIGZ1bmN0aW9uIGZvciBjb252ZXJ0aW5nIG51bWVyaWNhbCB2YWx1ZXMgdG8gb3JkZXJlZCBmYWN0b3JzIHVzZWQgZm9yIGNvdmVyYWdlIGFuZCBwb2xhcml6YXRpb24gbWVhc3VyZXMuICANCi0gT3ZlcmFsbCBybWFya2Rvd24gc3ludGF4IGxpa2UgY29sb3JpbmcsIGNzcyBzdHlsaW5nIGFuZCB3cml0aW5nIHBlcmlvZGljIG51bWJlcnMuICANCi0gV3JpdGluZyBlZmZpY2llbnQgY29kZS4gIA0KLSBSZWZvcm11bGF0aW9uIG9mIHNvbWUgc2VudGVuY2VzIGluIHRoZSBpbnRyb2R1Y3Rpb24gc2VjdGlvbiwgdGhlIGV4cGxhbmF0aW9uIG9mIE1vbnRlIENhcmxvIHNpbXVsYXRpb24sIGFzIHdlbGwgYXMgc29tZSBwYXJ0cyBvZiB0aGUgY29uY2x1c2lvbiBzZWN0aW9uLiAgDQoNCiMjIFJlZmVyZW5jZXMNCg0KLSBGaXNjaGVyLCBPLiwgJiBGcmV5LCBSLiAoMjAyMykuIFRoZSBtYW55IGZsYXZvcnMgb2YgcG9sYXJpemF0aW9uOiBBIHN5c3RlbWF0aWMgY29tcGFyaXNvbiBvZiBkaWZmZXJlbnQgY29uY2VwdHVhbGl6YXRpb25zIGFuZCBjb250ZXh0cy4gaHR0cHM6Ly9kb2kub3JnLzEwLjMxMjM0L29zZi5pby9idjQ5NiAgDQotIFBmaXN0ZXIsIFIuLCBTY2h3YXJ6LCBLLiBBLiwgSmFuY3p5aywgTS4sIERhbGUsIFIuLCAmIEZyZWVtYW4sIEouICgyMDEzKS4gR29vZCB0aGluZ3MgcGVhayBpbiBwYWlyczogQSBub3RlIG9uIHRoZSBiaW1vZGFsaXR5IGNvZWZmaWNpZW50LiAqRnJvbnRpZXJzIGluIFBzeWNob2xvZ3ksIDQqLiBodHRwczovL2RvaS5vcmcvMTAuMzM4OS9mcHN5Zy4yMDEzLjAwNzAwICANCi0gVmFuIERlciBFaWprLCBDLiAoMjAwMSkuIE1lYXN1cmluZyBhZ3JlZW1lbnQgaW4gb3JkZXJlZCByYXRpbmcgc2NhbGVzLiAqUXVhbGl0eSAmIFF1YW50aXR5IDM1LCAzMjXigJMzNDEqLiBodHRwczovL2RvaS5vcmcvMTAuMTAyMy9BOjEwMTAzNzQxMTQzMDUgIA0K